01谈谈Spring IOC的理解,原理与实现?
好的,我们看图说问题!
-
总的来说:
1.控制反转——原来的对象是由使用者来进行控制,有了spring之后,可以把整个对象交给spring来帮我们进行管理
2.DI依赖注入——把对应的属性的值注入到具体的对象中,@Autowired,populateBean完成属性值的注入
3.使用的容器——使用map结构来存储,在spring中一般存在三级缓存,singletonObjects存放完整的bean对象,整个bean的生命周期,从创建到使用到销毁的过程全部都是由容器来管理(bean的生命周期) -
说完总的,接下来我们根据图说细节:
1.beanFactry工厂的创建和xml配置文件的解析放到beanDefinition对象中;
-----容器是BeanDefinitionMap 存储beanName,beanDefinition对象;还有一个map是BeanDefinitionNames:存放beanDefinition的名称集合,后面会对这2个集合进行循环调用。
2. beanFactoryPostProcessor对BeanDefinition进行修改和增强。
-----beanFactoryPostProcessor的处理,这个方法主要是可以自由扩展,修改beanFactory中的相关信息,但是使用最多的是对BeanDefinition的修改操作,其中常用的有2个类,ConfigurationClassPostProcessor和PlaceHolderConfigurSupport吧,ConfigurationClassPostProcessor 会解析@Configuration,@ComponentScan,@Import,@Bean。
3.BeanPostProcessor的注册功能,方便后续对bean对象完成具体的扩展功能
-----其中还有一些方法,就是国际化的操作和监听器的创建
4.实例化对象
-----就是从容器中获取所有的BeanDefinitionNames集合 ,拿到beanDefinition对象进行实例化,在ioc 中使用的反射进行对象的创建,主要经历了getBean—doGetBean(此时缓存中有就直接返回,没有继续创建)—createBean()----doCreateBean(),在这里使用了函数式编程,调用getObject方法进到实际的创建方法中。
5.初始化对象
----(填充属性(解决了循环依赖的问题,向三级缓存中存放beanName和lambda表达式,把对象进行提前暴露),调用aware子类的方法(invokeAwareMethod(完成BeanName,BeanFactory,BeanClassLoader对象的属性设置)),调用BeanPostProcessor前置处理方法(ApplicationContextPostProcessor,设置ApplicationContext,Environment,ResourceLoader,EmbeddValueResolver等对象),调用init-mehtod方法(invokeInitmethod(),判断是否实现了initializingBean接口,如果有,调用afterPropertiesSet方法,没有就不调用),调用BeanPostProcessor的后置处理方法(这里主要是生成具体对象的代理对象,用于aop的使用,然后进行jdk或者cglib的代理实现))
6.生成完整的bean对象,通过getBean方法可以直接获取
7.销毁过程(1;判断是否实现了DispoableBean接口,2,调用destroyMethod方法)