Spring官网:
https://spring.io/
最新开发包及文档下载地址:
http://repo.springsource.org/libs-release-local/org/springframework/spring/
搞不懂之前的想法
想必大家一提起spring相关就会觉得很复杂,看了很多篇文章也是觉得很多深入底层的东西如此晦涩难懂。
提到spring就会想到循环依赖、事务、生命周期、设计模式、AOP、IOC、传播特性、源码等
本篇文章先从IOC开始慢慢学习,让我们在面对时候减少”迷糊“
spring其他一些特性会后续慢慢讲解,一切从源码出发,让我们对Spring有个清楚的认知!
一、spring是什么?
spring是一个轻量级开元框架,以IOC和AOP为内核,提供了开发过程中基本上所有的框架生成都依赖于spring,spring提供了(展现层)Spring MVC 和(持久层)Spring JDBC以及(业务层)事务管理等企业级应用技术,最为典型的就是数据库事务的使用,还能整合开元世界众多著名的第三方框架和类库,应该说ASpring框架已经融入了JavaEE的各个开发领域。
二、IOC 是什么?
Inverse of Control :控制反转
spring的核心,spring通过一个配置文件描述Bean及Bean之间的依赖关系,利用Java反射功能实例化Bean并建立Bean之间依赖关系。
控制:是容器对bean进行创建、管理。控制bean的整个生命周期。
反转:我们是被动接受Spring容器创建的对象,而不是自己主动去控制。
总结:负责控制对象的生命周期和对象间的关系
三、DI
依赖:应用程序依赖IoC容器,在程序运行的时候,应用程序需要IoC容器来提供对象需要的外部资源;
注入:IoC容器注入应用程序的某个对象,注入了其所需要的的外部资源(对象、资源和数据等);
所以说控制反转是通过依赖注入实现的,其实它们是同一个概念的不同角度描述。通俗来说就是IoC是设计思想,DI是实现方式
四、探索bean的生命周期
ioc设计思想本质就是把对象交给容器控制,那么我们的bean是怎么创建的呢?
1.我想创建一个bean,于是我找到了spring先生,他说他家开了一个BeanFactory工厂,可以自动化加工我想要的bean,后续他帮我管理,他叫我别操心了。我专心一想不错,拍案叫绝啊!
spring先生说你叫我创建的话怎么的也的给我一个你理想的bean是什么样子的吧!
我想也是,那我就落实在配置文件上吧,于是我想到了用xml、properties、json、注解等去描述下我的bean
2.spring一想,这我想读取这些配置文件怎么办呢?弄个读取器吧,每种配置文件写一个读取器不利于扩展,那就写个读取器接口吧!
3.我说行,那我先不管了,放心的交给你了
spring先生在读取之后然后想得把bean定义的信息封装成自己的格式吧,不如就叫做BeanDefinition
我:那为啥不用class信息注册啊?
spring先生:你看看,它帮我记录了多少有用的信息!
我:妙啊!
读完配置文件之后,得到了很多的BeanDefinition对象,
4.那定义完了是不是就要交给beanFactory工厂帮我创建了呀,但是实例化之前配置下元数据,并且看需修改一下
spring一听那我给你一个接口吧 BeanFactoryPostProcessor,你自己扩展得了,少烦我
5.通过BeanDefinitionRegistry注册到beanFactory后就要进行实例化bean了
spring先生觉得,这么多bean注册到我这里,我需要把注册的bean保存下来呀,于是想到了保存ConcurrentHashMap中
但是接下来呢,实例化都需要哪些过程呢,
6.spring先生一想,那就先给这个bean在内存中找个地方,然后把它的属性给它,最后它不用的就要销毁
也就是:实例化 -> 属性赋值 -> 初始化 -> 销毁
初始化呢spring先生提供了init-method方法,但是我想在初始化前后执行我自己想要的扩展逻辑怎么办呢?于是spring先生在执行init-method方法前后都调用了bean后至处理器的postProcessBeforeInitialization()
方法和postProcessAfterInitialization()
方法方法
7.我想把spring底层组件注入到我自己定义的bean中,然后再调用相应的processor处理器处理怎么办呢?spring提供了aware接口供我扩展,如果我需要使用ApplicationContext、BeanFactory,那我就可以通过写ApplicationContextAware、BeanFactoryAware等接口实现
ApplicationContextAware是利用ApplicationContextAwareProcessor来处理的,XxxAware也有相应的processor进行处理,其实就是相关后置处理器完成处理工作
所以BeanNameAware
接口是为了让自身Bean
能够感知到,获取到自身在Spring容器中的id属性。
同理,其他的Aware
接口也是为了能够感知到自身的一些属性。
7.最后我用完了,spring帮我利用destroy-method销毁
总结:
- 实例化bean对象(通过构造方法或者工厂方法)
- 设置对象属性(setter等)(依赖注入)
- 如果实现aware接口,就执行相应方法
- 将Bean实例传递给Bean的前置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法
- 调用Bean的初始化方法 init-method
- 将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法
- 使用Bean
- 容器关闭之前,调用Bean的销毁方法- destroy-method
五、整体架构
六、源码
请看下一章