Spring Bean的生命周期以及IOC源码解析

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()方法

销毁在容器关闭是时候执行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值