IOC源码这一块太多只能讲个大概吧,建议还是去买本Spring IOC源码解析的书来看比较好,我也是自己看源代码以及视频整理的笔记
Bean的生命周期大概可以分为四个阶段,具体的等会再说,先看看IOC的源码吧
1、bean的创建
2、bean的属性赋值
3、bean的初始化
4、bean的销毁
IOC容器源码解析
我们创建容器以new AnnotationConfigApplicationContext(Config.class)为示例,我们点开源代码,看一下
其实做了挺多事的,在父类的的无参构造函数当中,就创建了一个BeanFactory的实例,其实可以去看一下这个类的无参构造函数,其实加载了很多必备的Bean到容器当中,例如之前提到过的一些常用的BeanPostProcessor,这里就不多说了,不然博客会太长了
接下来就是第一个方法register(componentClasses)解析配置类的注解,并且创建了BeanFactory的实例(org.springframework.beans.factory.support.DefaultListableBeanFactory的实例)并且将配置类注入到容器中
方法点进去之后能看到
我们进到注册Bean的方法(BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);)里面
我们看一下是怎么注入的
其实就是将对象包装成BeanDefinition对象,然后添加到ConcurrentHashMap当中。
第二部,进入到refresh()方法,但是该方法位于父类的org.springframework.context.support.AbstractApplicationContext.class的515行,这个是一个刷新方法,将我们的业务Bean注入进去
无论是通过哪种创建Spring 的ioc容器都会执行这个refresh方法。大致的主要方法如下,不过有些方法的细节就不讲了,IOC过于庞大,懂个大概就差不多了,但是方法具体是干嘛的会一个一个讲
prepareRefresh()
1)、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;
2)、getEnvironment().validateRequiredProperties();检验属性的合法等
3)、earlyApplicationEvents= new LinkedHashSet<ApplicationEvent>();保存容器中的一些早期的事件;
obtainFreshBeanFactory()
获取到BeanFactory对象
prepareBeanFactory(beanFactory)
设置一下BeanFactory对象一些属性
1)、设置BeanFactory的类加载器、支持表达式解析器...
2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
3)、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
4)、注册可以解析的自动装配;我们能直接在任何组件中自动注入:BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5)、添加BeanPostProcessor【ApplicationListenerDetector】
6)、添加一些loadTimeWeaver;
7)、给BeanFactory中注册一些能用的组件;
environment【ConfigurableEnvironment】、
systemProperties【Map<String, Object>】、
systemEnvironment【Map<String, Object>】
postProcessBeanFactory(beanFactory)
BeanFactory完成的后置工作,当前为空,但是可以继承当前类,在子类中可以实现这个方法
invokeBeanFactoryPostProcessors(beanFactory)
加载并执行BeanFactoryPostProcessor以及BeanDefinitionRegistryPostProcessor这两个接口的两个实现方法
1、postProcessBeanFactory()
2、postProcessBeanDefinitionRegistry():
这个方法里面做了很多加载,这里就不展示,自行去看源码吧
initMessageSource()
注册一个MessageSource的对象,但是这个Bean并没有加载到之前的那个Map当中,而是加载到一个缓存的Map当中,用于解决循环依赖
initApplicationEventMulticaster()
初始化一个派发器,跟上面那个差不多,只是对象不一样
onRefresh()
跟之前的那个postProcessorBeanFactory方法差不多,留给子类实现
registerListeners()
注册监听器,实现ApplicationListener<?>接口,并指定时在什么时候加载即指定ContextEvent
finishBeanFactoryInitialization(beanFactory)
这个就是加载所有业务单实例Bean的方法,并且生命周期都会在这里执行,首先会配置一些BeanFactory的一些属性,然后在加载业务Bean
第一部分优先获取Bean名称的一些定义信息getMergedLocalBeanDefinition(beanName),然后先处理实现FactoryBean的Bean
点进去getBean(beanName)之后,调用方法 doGetBean(name, null, null, false),这个方法就不贴截图了,代码太多不好截图,可以自己去对照这源码看,就讲调用了哪个方法就好了。
Object sharedInstance = getSingleton(beanName) 从缓存的Bean中去获取看看在不在,如果存在的话就直接获取(会去校验FactoryBean缓存中是否存在),不存在就执行else方法
如果缓存中不存在的话,就是一个新的Bean等待创建
运行到了markBeanAsCreated(String beanName),这个是用来标记当前beanName已经存在了,将beanName添加到alreadyCreated集合当中,然后运行到了下面
然后继续执行
进入到createBean()方法后,有个获取代理的方法,这个方法就得讲一下,跟Spring的AOP以及事务有关
Object bean = resolveBeforeInstantiation(beanName, mbdToUse)讲解:
我们点开查看一下这个方法,有个createProxy()创建代理方法
进入到创建代理的方法里面,我们看一下
我们点开getProxy方法,会返回一个createAopProxy().getProxy(classLoader);对象,我们依次点开后,在使用AOP到底是JDK动态代理还是CGLIB代理的关键所在
好了,代理的那个方法差不多了,我们改回到正题了
我们进入到Object beanInstance = doCreateBean(beanName, mbdToUse, args);
有个BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);这个是创建BeanWrapper的包装类,在createBeanInstance方法中最后会执行instantiateBean()
我们进入到这个instantiate(),最后有个BeanUtils.instantiateClass(constructorToUse)方法用来创建对象,这就不深入的讨论了,大家可以自己去看
然后包装一个BeanWrapperImpl对象,最后返回出去;创建好后,进行属性赋值以及Bean的初始化,在属性赋值的方法里面有个InstantiationAwareBeanPostProcessors方法执行
我们看下初始化方法
Bean的初始化,会先加载Aware,然后调用BeanPostProcessor的前置方法,然后加载初始化方法,再加载BeanPostProcessor的后置方法
这个方法基本就加载完了
finishRefresh()
加载完业务Bean的一些工作
resetCommonCaches()
这个是处于finally代码块的方法用来清除创建时临时缓存数据
Bean生命周期
在上面IOC分析里面已经提到了Bean的创建以及属性赋值了
接下来就是初始化以及销毁
初始化
初始化使用的方法有三种
1、@Bean(initMethod = "")调用指定初始化方法
2、在类中设置@PostConstruct注解
3、实现InitializingBean接口,实现afterPropertiesSet()方法
销毁
对应的销毁也有三种
1、@Bean(destroyMethod= "")调用指定销毁方法
2、在类中设置@PreDestroy注解
3、实现DisposableBean接口,实现destroy()方法
销毁在容器关闭是时候执行