Spring 框架源码(六) Bean的生命周期全流程源码解析
创始人
2024-05-26 09:24:24
0

        如果用了Spring框架几年,只听说过IOC,不知道IOC核心实现的伙伴们来看一下本篇文章。

        Spring框架作为Java王国的地基,我觉得它包含了很多精妙的设计,例如Bean工厂设计、Bean的生命周期、tx、aop、web、mvc等,最核心基本的Bean设计是Spring 的框架的灵魂,本文就Bean的生命周期全流程做源码程度上的解析,欢迎各位大佬指点江山。

        Bean的生命周期贯彻整个IOC的流程,那么Spring是如何实现IOC的?先上一张DefaultListableBeanFactory的UML图来来感受Spring IOC设计的强大,跟着DefaultListableBeanFactory去揭开Spring框架的核心面纱, 大家可以根据需要自取下图。

一、DefaultListableBeanFactory  

        DefaultListableBeanFactory掌管了Bean生命周期的大权,Bean的创建、初始化、销毁,添加BeanPostProcessor等功能,可以说是Spring框架最全的Bean工厂, 掌握DefaultListableBeanFactory 是非常有必要的。

1. 创建并注册BeanDefinition

        我们可以使用DefaultListableBeanFactory 对象注册一个BeanDefition, 使用registerBeanDefinition()方法, 如果想要加入一个BeanPostProcessor, 可以使用addBeanPostProcessor()方法。

	private DefaultListableBeanFactory createBeanByDefaultListableBeanFactory(final Class beanClass) {DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass);beanDefinition.setInitMethodName("testMethod");beanDefinition.setDestroyMethodName("testDestroy");beanFactory.registerBeanDefinition("testBean", beanDefinition);//添加BeanPostProcessorbeanFactory.addBeanPostProcessor(new BeanPostProcessor() {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {//System.out.println("执行前..");return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {System.out.println("执行后..");return bean;}});return beanFactory;}public static class User {public void testMethod(){System.out.println("初始化..");}public void testDestroy(){System.out.println("销毁..");}}@Testpublic void testDefaultListableBeanFactory() {final Class beanClass = User.class;DefaultListableBeanFactory beanFactory = createBeanByDefaultListableBeanFactory(beanClass);User user = beanFactory.getBean("testBean", User.class);System.out.println("user= " + user);}

打印结果:

从打印结果可以知道User这个Bean的三个方法的执行顺序: 

postProcessBeforeIntialization()> init-method()>postProcessAfterInitialization()

2. 三级缓存设计

        DefaultListableBeanFactory里设计了三级缓存,三级缓存只针对单例Bean, 该三级缓存分别是: singletonObjects, earlySingletonObjects, singletonFactoirese。

/** Cache of singleton objects: bean name --> bean instance */
private final Map singletonObjects = new ConcurrentHashMap<>(256);/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map> singletonFactories = new HashMap<>(16);/** Cache of early singleton objects: bean name --> bean instance */
private final Map earlySingletonObjects = new HashMap<>(16);

        有依赖的情况下获取Bean:

	/*** Return the (raw) singleton object registered under the given name.* 

Checks already instantiated singletons and also allows for an early* reference to a currently created singleton (resolving a circular reference).* @param beanName the name of the bean to look for* @param allowEarlyReference whether early references should be created or not* @return the registered singleton object, or {@code null} if none found*/@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {//尝试从二级缓存里singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {// 从三级缓存里拿到ObjectFactory后,创建一个实例添加到二级缓存里singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;}

1. 先从一级缓存里拿, 如果有直接返回。

2. 如果从一级缓存里没有拿到Bean的实例,那么尝试从二级缓存里拿,如果有直接返回,没有执行步骤3.

3. 从三级缓存里根据BeanName获取到ObjectFactory接口实例,使用getObject()方法获取到实例后,加入到二级缓存同时返回实例。

        由于篇幅过长的问题,后续会单独写一篇Spring框架为什么要设计三级缓存,如果没有三级缓存能不能行?欢迎大家持续关注。

        我们都知道Spring 通过自动装配来实现Bean的初始化,当我们在用Bean的依赖属性时都已经完成了初始化,而不是一个Null, 那么Spring 是如何实现IOC的?

二、Bean属性填充和实例化过程源码解析

        在创建Bean时会进入到AutowireCapableBeanFactory的 doCreateBean方法:

         两个核心方法分别实现是: 属性填充populateBean、初始化Bean。

Bean属性填充

        进入到populeBean方法,看是如何根据RootBeanDefinition和instanceWrapper来填充的

Populate the bean instance in the given BeanWrapper with the property values.

根据BeanWrapper来填充Bean属性。

根据构造器推断选择使用哪种装配模式 

        AutowireCapableBeanFactory接口里定义了Bean属性的装配方式,我们要核心掌握3种:

根据名称来装配AUTOWIRE_BY_NAME

根据Type来装配AUTOWIRE_BY_TYPE

根据构造器来装配AUTOWIRE_CONSTRUCTOR

	/*** Constant that indicates no externally defined autowiring. Note that* BeanFactoryAware etc and annotation-driven injection will still be applied.* @see #createBean* @see #autowire* @see #autowireBeanProperties*/int AUTOWIRE_NO = 0;/*** Constant that indicates autowiring bean properties by name* (applying to all bean property setters).* @see #createBean* @see #autowire* @see #autowireBeanProperties*/int AUTOWIRE_BY_NAME = 1;/*** Constant that indicates autowiring bean properties by type* (applying to all bean property setters).* @see #createBean* @see #autowire* @see #autowireBeanProperties*/int AUTOWIRE_BY_TYPE = 2;/*** Constant that indicates autowiring the greediest constructor that* can be satisfied (involves resolving the appropriate constructor).* @see #createBean* @see #autowire*/int AUTOWIRE_CONSTRUCTOR = 3;/*** Constant that indicates determining an appropriate autowire strategy* through introspection of the bean class.* @see #createBean* @see #autowire* @deprecated as of Spring 3.0: If you are using mixed autowiring strategies,* prefer annotation-based autowiring for clearer demarcation of autowiring needs.*/@Deprecatedint AUTOWIRE_AUTODETECT = 4;

这3个类型分别定义在AbstarctBeanDefinition类里, 在populateBean时会用到, 接着进入到populateBean方法:

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw);

根据Name和Type装配Bean: 

		if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {MutablePropertyValues newPvs = new MutablePropertyValues(pvs);// Add property values based on autowire by name if applicable.if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {autowireByName(beanName, mbd, bw, newPvs);}// Add property values based on autowire by type if applicable.if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {autowireByType(beanName, mbd, bw, newPvs);}pvs = newPvs;}

根据Name填充

        接下来进入autowireByName方法,深入理解是怎么根据name进行装配的。

	protected void autowireByName(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {//获取到当前BeanDefinition下所有的属性String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {// 根据name从容器里如果能找到该Beanif (containsBean(propertyName)) {Object bean = getBean(propertyName);// 为依赖的Bean填充属性pvs.add(propertyName, bean);// 将依赖的Bean用map管理起来registerDependentBean(propertyName, beanName);if (logger.isDebugEnabled()) {logger.debug("Added autowiring by name from bean name '" + beanName +"' via property '" + propertyName + "' to bean named '" + propertyName + "'");}}else {if (logger.isTraceEnabled()) {logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +"' by name: no matching bean found");}}}}

         先根据unsatisfiedSimpleProperties方法来获取到当前BeanDefinition下所有的属性, 然后从容器里判断Bean是否存在,如果已经存在,那么通过pvs.add(propertyName, bean) 将从容器里拿出的Bean赋值给propertyName对应的Bean。

        最后当前Bean依赖的Bean 存放到DefaultSingletonBeanRegistry的dependentBeanMap和dependenciesForBeanMap里缓存起来。

根据Type填充

	protected void autowireByType(String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {TypeConverter converter = getCustomTypeConverter();if (converter == null) {converter = bw;}Set autowiredBeanNames = new LinkedHashSet<>(4);String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);for (String propertyName : propertyNames) {try {PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);// Don't try autowiring by type for type Object: never makes sense,// even if it technically is a unsatisfied, non-simple property.if (Object.class != pd.getPropertyType()) {MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);// Do not allow eager init for type matching in case of a prioritized post-processor.boolean eager = !PriorityOrdered.class.isInstance(bw.getWrappedInstance());DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);if (autowiredArgument != null) {//填充属性pvs.add(propertyName, autowiredArgument);}for (String autowiredBeanName : autowiredBeanNames) {// 缓存依赖的BeanregisterDependentBean(autowiredBeanName, beanName);if (logger.isDebugEnabled()) {logger.debug("Autowiring by type from bean name '" + beanName + "' via property '" +propertyName + "' to bean named '" + autowiredBeanName + "'");}}autowiredBeanNames.clear();}}catch (BeansException ex) {throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);}}}

        为了进一步理解Bean的生命周期,下面我们继续看Aware、BeanPostProcessor、InitialzingBean接口的执行顺序。 

初始化Bean

initializeBean方法实现了实例化Bean的整个流程。

	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged((PrivilegedAction) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {// 1. 执行所有的BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口,把对象塞入到参数里交给开发者使用。invokeAwareMethods(beanName, bean);}// 2. 执行所有的BeanPostProcessor里的postProcessBeforeInitialization()Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {// 3. 执行Init方法, 其中包含InitializingBean接口里的AfterPropertiesSet()方法和自定义的init()方法invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}//4. 执行所有的BeanPostProcessor的postProcessAfterInitialization()方法if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;} 

        该方法执行顺序分析:

1. 通过InvokeAwareMethods执行BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口定义的方法。

2. 执行BeanPostProcessor列表里所有的BeanPostProcessor的PostProcessBeforeInitialization()方法。

3. 通过invokeInitMethod()执行init-method。

4. 执行IntializingBean接口里的AfterPropertiesSet()方法。

5. 执行BeanPostProcessor列表里所有的BeanPostProcessor的PostProcessAfterInitialization()方法。

BeanNameAware、BeanFactoryAware、BeanClassLoaderAware

        BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口分别是在初始化Bean之前调用的,我们可以利用BeanName、BeanFactory、ClassLoader去开发一些业务。

	/***  执行BeanNameAware、BeanClassLoaderAware、BeanFactoryAware的接口。* @param beanName* @param bean*/private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}

BeanPostProcessor在这里是在Aware之后调用的,接着看BeanPostProcessor接口。

BeanPostProcessor

        BeanPostProcessor接口里有2个默认方法,分别为PostProcessBeforeInitialization和PostProcessAfterInitialization。

public interface BeanPostProcessor {/*** Apply this BeanPostProcessor to the given new bean instance before any bean* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}* or a custom init-method). The bean will already be populated with property values.* The returned bean instance may be a wrapper around the original.* 

The default implementation returns the given {@code bean} as-is.* @param bean the new bean instance* @param beanName the name of the bean* @return the bean instance to use, either the original or a wrapped one;* if {@code null}, no subsequent BeanPostProcessors will be invoked* @throws org.springframework.beans.BeansException in case of errors* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet*/@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}/*** Apply this BeanPostProcessor to the given new bean instance after any bean* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}* or a custom init-method). The bean will already be populated with property values.* The returned bean instance may be a wrapper around the original.*

In case of a FactoryBean, this callback will be invoked for both the FactoryBean* instance and the objects created by the FactoryBean (as of Spring 2.0). The* post-processor can decide whether to apply to either the FactoryBean or created* objects or both through corresponding {@code bean instanceof FactoryBean} checks.*

This callback will also be invoked after a short-circuiting triggered by a* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,* in contrast to all other BeanPostProcessor callbacks.*

The default implementation returns the given {@code bean} as-is.* @param bean the new bean instance* @param beanName the name of the bean* @return the bean instance to use, either the original or a wrapped one;* if {@code null}, no subsequent BeanPostProcessors will be invoked* @throws org.springframework.beans.BeansException in case of errors* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet* @see org.springframework.beans.factory.FactoryBean*/@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}

InitializingBean

        InitializingBean接口官方解释: 当所有的Bean属性被BeanFactory设置完后允许你用afterPropertieSet()方法做一次调。

/*** Interface to be implemented by beans that need to react once all their* properties have been set by a BeanFactory: for example, to perform custom* initialization, or merely to check that all mandatory properties have been set.** 

An alternative to implementing InitializingBean is specifying a custom* init-method, for example in an XML bean definition.* For a list of all bean lifecycle methods, see the* {@link BeanFactory BeanFactory javadocs}.** @author Rod Johnson* @see BeanNameAware* @see BeanFactoryAware* @see BeanFactory* @see org.springframework.beans.factory.support.RootBeanDefinition#getInitMethodName* @see org.springframework.context.ApplicationContextAware*/ public interface InitializingBean {/*** Invoked by a BeanFactory after it has set all bean properties supplied* (and satisfied BeanFactoryAware and ApplicationContextAware).*

This method allows the bean instance to perform initialization only* possible when all bean properties have been set and to throw an* exception in the event of misconfiguration.* @throws Exception in the event of misconfiguration (such* as failure to set an essential property) or if initialization fails.*/void afterPropertiesSet() throws Exception;}

该接口一般可以用来做属性实例的校验,比如当前Bean依赖了哪些Bean, 如果依赖的Bean没有初始化,就应该抛出异常,例如DataSourceTransactionManager里用该方法去校验DataSource有没有被初始化。

public class DataSourceTransactionManager extends AbstractPlatformTransactionManagerimplements ResourceTransactionManager, InitializingBean {@Nullableprivate DataSource dataSource;private boolean enforceReadOnly = false;/*** Create a new DataSourceTransactionManager instance.* A DataSource has to be set to be able to use it.* @see #setDataSource*/public DataSourceTransactionManager() {setNestedTransactionAllowed(true);}/*** Create a new DataSourceTransactionManager instance.* @param dataSource JDBC DataSource to manage transactions for*/public DataSourceTransactionManager(DataSource dataSource) {this();setDataSource(dataSource);afterPropertiesSet();}@Overridepublic void afterPropertiesSet() {if (getDataSource() == null) {throw new IllegalArgumentException("Property 'dataSource' is required");}}}

        InitializingBean接口的afterPropertiesSet()在AbstractAutowireCapableBeanFactory的invokeInitMethods方法里被调用。

	protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);// 执行InitializingBean的afterPropertiesSet()if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {if (logger.isDebugEnabled()) {logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");}if (System.getSecurityManager() != null) {try {AccessController.doPrivileged((PrivilegedExceptionAction) () -> {((InitializingBean) bean).afterPropertiesSet();return null;}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {// 执行InitialingBean的afterProperties()接口。((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null && bean.getClass() != NullBean.class) {String initMethodName = mbd.getInitMethodName();if (StringUtils.hasLength(initMethodName) &&!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}}                
            
            
            
            
            
            

相关内容

热门资讯

7月4日创业板200ETF易方... 7月4日,创业板200ETF易方达(159572)跌0.73%,成交额1671.93万元。当日份额减...
7月4日港股互联网ETF(15... 7月4日,港股互联网ETF(159568)跌0.66%,成交额1.19亿元。当日份额增加300.00...
7月4日科创芯片ETF南方(5... 7月4日,科创芯片ETF南方(588890)涨0.00%,成交额3728.13万元。当日份额减少30...
7月4日创业板50ETF(15... 7月4日,创业板50ETF(159949)跌0.21%,成交额9.10亿元。当日份额减少9000.0...
7月4日证券ETF南方(512... 7月4日,证券ETF南方(512900)跌0.09%,成交额7912.32万元。当日份额增加650....
7月4日A50ETF(5121... 7月4日,A50ETF(512150)涨0.66%,成交额538.09万元。当日份额减少200.00...
7月4日中证A500ETF龙头... 7月4日,中证A500ETF龙头(563800)涨0.31%,成交额9.52亿元。当日份额减少1.1...
7月4日A500ETF工银(1... 7月4日,A500ETF工银(159362)涨0.20%,成交额4697.58万元。当日份额减少21...
7月4日上证180ETF南方(... 7月4日,上证180ETF南方(530580)涨0.40%,成交额3335.63万元。当日份额减少1...
7月4日港股红利低波ETF(5... 7月4日,港股红利低波ETF(520550)跌0.08%,成交额1.07亿元。当日份额增加4850....