详细聊聊Spring核心思想( 二 )

详细聊聊Spring核心思想

文章插图
 
拔高了这个思想后,编码的逻辑就从我们程序员想着且写着 ServiceA 依赖具体的 ServiceB,且一个字母一个字母的敲完 ServiceB 具体是如何实例化的代码,变成我们只关心 ServiceA 依赖 ServiceB,但 ServiceB 是如何生成的我们不管,由那个“东西”帮我们生成它且关联好 ServiceA 和 ServiceB 。
public class ServiceA {@注入private ServiceB serviceB;}听起来好像有点悬乎,其实不然 。
还是拿机器说事,我们创造这台机器,如果要生产产品 A,我们只要画好图纸 A,将图纸 A 塞到这个机器里,机器识别图纸 A,按照我们图纸 A 的设计制造出我们要的产品 A 。
Spring就是这台机器,图纸就是依托 Spring 管理的对象代码以及那些 XML 文件(或标注了@Configuration的类) 。
这时候逻辑就转变了 。程序员知道 ServiceA 具体依赖哪个 ServiceB,但是我们不需要显示的在代码中写上完整的关于如何创建 ServiceB 的逻辑,我们只需要写好配置文件,具体地创建和关联由 Spring 帮我们做 。
继续拿机器举例,我们给了图纸(配置),机器帮我们制造产品,具体如何制造出来不需要我们操心,但是我们心里是有数的,因为我们的图纸写明了制造 ServiceA 需要哪样的 ServiceB,而那样的 ServiceB 又需要哪样的 ServiceC等等逻辑 。
我找个图纸例子,Spring 里关于数据库的配置:
详细聊聊Spring核心思想

文章插图
 
可以看到我们的图纸写的很清楚,创建 MyBatis 的MApperScannerConfigurer需要告诉它两个属性的值,比如第一个是sqlSessionFactoryBeanName,值是 sqlSessionFactory 。
而sqlSessionFactory又依赖 dataSource,而 dataSource 又需要配置好 driverClassName、url 等等 。
所以,其实我们心里很清楚一个产品(Bean)要创建的话具体需要什么东西,只过不这个创建过程由 Spring 代劳了,我们只需要清楚的告诉它即可 。
因此,不是说用了 Spring 我们不再关心 ServiceA 具体依赖怎样的 ServiceB、ServiceB具体是如何创建成功的,而是说这些对象组装的过程由 Spring 帮我们做好 。
我们还是需要清楚地知道对象是如何创建的,因为我们需要画好正确的图纸告诉 Spring 。
所以 Spring 其实就是一台机器,根据我们给它的图纸,自动帮我们创建关联对象供我们使用,我们不需要显示得在代码中写好完整的创建代码 。
这些由 Spring 创建的对象实例,叫作 Bean 。
我们如果要使用这些 Bean 可以从 Spring 中拿,Spring 将这些创建好的单例 Bean 放在一个 Map 中,通过名字或者类型我们可以获取这些 Bean 。
这就是 IOC 。
也正因为这些 Bean 都需要经过 Spring 这台机器创建,不再是懒散地在代码的各个角落创建,我们就能很方便的基于这个统一收口做很多事情 。
详细聊聊Spring核心思想

文章插图
 
比如当我们的 ServiceB 标注了 @Transactional 注解,由 Spring 解析到这个注解就能明白这个 ServiceB 是需要事务的,于是乎织入的事务的开启、提交、回滚等操作 。
但凡标记了 @Transactional 注解的都自动添加事务逻辑,这对我们而言减轻了太多重复的代码,只要在需要事务的方法或类上添加 @Transactional注解即可由 Spring 帮我们补充上事务功能,重复的操作都由 Spring 完成 。
再比如我们需要在所有的 controller 上记录请求入参,这也非常简单,我们只要写个配置,告诉 Spring xxx路径(controller包路径)下的类的每个方法的入参都需要记录在 log 里,并且把日志打印逻辑代码也写上 。
Spring 解析完这个配置后就得到了这个命令,于是乎在创建后面的 Bean 时就看看它所处的包是否符合上述的配置,若符合就把我们添加日志打印逻辑和原有的逻辑编织起来 。
这样就把重复的日志打印动作操作抽象成一个配置,Spring 这台机器识别配置后执行我们的命令完成这些重复的动作 。
这就叫 AOP 。
至此我相信你对 Spring 的由来和核心概念有了一定的了解,基于上面的特性能做的东西有很多 。
因为有了 Spring 这个机器统一收口处理,我们就可以灵活在不同时期提供很多扩展点,比如配置文件解析的时候、Bean初始化的前后,Bean实例化的前后等等 。


推荐阅读