从Spring源码分析Bean的生命周期

1.背景

每天都离不开Spring,到现在还没认真研究过Spring的源码,对Spring中bean的生命周期也是一知半解,恰好最近研究RcoketMQ源码,想要手写一个RocketMQ注入Spring的小demo,但是发现对于如何使用Spring中的各种方式不了解,以及注入ProducerBean与ConsumerBean的时机也不是了解,借此机会深入研究下Spring源码。

2.过程

研究过程直接上手Spring源码会有点难以接受,不太方便找逻辑,跟着小傅哥的文章走了一遍,文章链接

跟自己以前的认知一样,从IOC容器的创建,bean的实例化、解析xml文件生成bean、getBean、属性注入、初始化bean、以及BeanFactoryPostProcessor、BeanPostProcessor、ApplicationContext、ApplicationContextAware、BeanNameAware等接口的使用和实现。

此次周期一周、每天耗时1.5小时,完成了最基本的Spring基础功能,在此基础上再阅读源码就事半功倍,知道如何追踪整个过程。

3.实现

3.1.容器的创建

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
 		
    //bean容器,该容器中存放的不是直接使用的bean,而是通用的beanDefinition,
    //该对象中主要的属性有Class类,单例/原型,bean的属性值等。容器的key是beanName
    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
		
    
    //bean注入容器的方法
    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException {
        //...省略
        //判断bean是否存在容器中,
        BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
          if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
          }
          else if (existingDefinition.getRole() < beanDefinition.getRole()) {
            // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
            if (logger.isInfoEnabled()) {
              logger.info("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  existingDefinition + "] with [" + beanDefinition + "]");
            }
          }
          else if (!beanDefinition.equals(existingDefinition)) {
            if (logger.isDebugEnabled()) {
              logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
            }
          }
          else {
            if (logger.isTraceEnabled()) {
              logger.trace("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + existingDefinition +
                  "] with [" + beanDefinition + "]");
            }
          }
          this.beanDefinitionMap.put(beanName, beanDefinition);
        }
        else { 
            //若容器中不存在bean,则需要注入到容器总,这里使用synchronized加锁保证线程安全
            //这里做判断,判断该bean是否已经开始了创建,如果是则需要执行后续逻辑,同时再注入一次容器
          if (hasBeanCreationStarted()) {
            // Cannot modify startup-time collection elements anymore (for stable iteration)
            synchronized (this.beanDefinitionMap) {
              this.beanDefinitionMap.put(beanName, beanDefinition);
              //...省略
            }
          }
          else { //若还未创建beanDefinition,则将该beanefinition进行注入
            // Still in startup registration phase
            this.beanDefinitionMap.put(beanName, beanDefinition);
            this.beanDefinitionNames.add(beanName);
            this.manualSingletonNames.remove(beanName);
          }
          this.frozenBeanDefinitionNames = null;
        }

        if (existingDefinition != null || containsSingleton(beanName)) {
          resetBeanDefinition(beanName);
        }
    }  
    //...省略
}
复制代码

容器的创建主要依赖于beanDefinitionMap,该容器就是一个K-V容器,K是beanName,value是beanDefinition,将该逻辑简单化就是最简单的K-V的put。

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements BeanDefinitionRegistry, ConfigurableListableBeanFactory {

	private Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    @Override
    public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) {
        beanDefinitionMap.put(beanName, beanDefinition);
    }
}
复制代码

那么registerBeanDefinition的调用方是什么呢?这就是bean的注入。

3.2.beanDefinition的注入

看源码中registerBeanDefinition的调用方很多,但是很多并不是直接关系bean的生命周期,因此主要关注bean生命周期的调用的话,主要涉及的是org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition

该方法中是工具类中暴漏的静态方法,该方法逻辑也简单就是组装容器的K-V,然后调用registerBeanDefinition.

public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // Register bean definition under primary name.
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // Register aliases for bean name, if any.
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}
复制代码

而该方法的调用方主要有两个地方,一个是读取注解Component注入到容器的地方,一个是读取xml解析bean注入到容器的地方,主要涉及以下两个类

//该类是ClassPatch的扫描类
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
		//该方法可以理解为当平时在一些类中加入了Conponent注解时,Spring就会通过该方法扫描到这些类,然后将这些类注入到容器中
    	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
			Assert.notEmpty(basePackages, "At least one base package must be specified");
            Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
            for (String basePackage : basePackages) {
                //将加了注解Component的类进行解析
                Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
                for (BeanDefinition candidate : candidates) {
                    //单例/原型模式判断
                    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
                    candidate.setScope(scopeMetadata.getScopeName());
                    //获取beanName
                    String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                    if (candidate instanceof AbstractBeanDefinition) {
                        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
                    }
                    if (candidate instanceof AnnotatedBeanDefinition) {
                        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
                    }
                    if (checkCandidate(beanName, candidate)) {
                        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                        definitionHolder =
                                AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                        beanDefinitions.add(definitionHolder);
                        //调用注入容器方法
                        registerBeanDefinition(definitionHolder, this.registry);
                    }
                }
            }
		return beanDefinitions;
	}
    
    //注入bean的方法
    protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
	}


}
复制代码

(通过这个类就知道了为什么加个注解就可以将类注入到容器了)

//该类是获取xml配置文件bean的实现类,比如XmlBeanDefinitionReader类最终会调用到此处
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
	//读取xml配置文件的元素
    protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
   		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
   		if (bdHolder != null) {
     			 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
      			try {
        	 	// 注入容器的调用方,通过该方法将读取到的xml文件解析成beanDefinition然后注入到容器
         		BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
      			}
      			catch (BeanDefinitionStoreException ex) {
         			getReaderContext().error("Failed to register bean definition with name '" +
               		bdHolder.getBeanName() + "'", ele, ex);
      			}
      			// Send registration event.
      			getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
   		}
	}
}
复制代码

(通过该类就知道为啥读取到的xml文件为什么能解析成bean注入到容器了)

3.3.bean的获取

以上逻辑主要是进行bean实例的注入,但是bean实例并不是我们直接使用的对象,bean实例需要转换成bean才可以对外使用,因此获取bean的方式就通过核心接口BeanFactory实现。

BeanFactory接口一定非常熟悉,它定义了最基础的功能getBean,主要涉及如下:

public interface BeanFactory {

	
	String FACTORY_BEAN_PREFIX = "&";

	
	Object getBean(String name) throws BeansException;

	
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	
	Object getBean(String name, Object... args) throws BeansException;

	
	<T> T getBean(Class<T> requiredType) throws BeansException;

	
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;

	
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

	
	boolean containsBean(String name);

	
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;


	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;


	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;


	String[] getAliases(String name);

}
复制代码

该接口提供了最基础的操作bean的方式,具体的实现则交给具体的实现类进行实现,大大提高了扩展性。

以最基本的**Object getBean(String name)**方法为例,它的实现是如何做的呢。

前面说的容器的创建是对bean实例的容器,刺客需要获取bean,那么就需要一个bean容器。

bean容器的实现如下:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    //bean容器,缓存了bean对象,K-V格式,K代表beanName,getBean等方法都是从该容器中获取,同时该容器还是三级缓存模型的一级缓存。
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    
}
复制代码

因此当执行getBean(String beanName)时,就是从singletonObjects中获取bean对象。

BeanFactory的实现类主要有两个,分别是AbstractBeanFactory和AbstractApplicationContext,两个抽象类都分别实现了BeanFactory中的方法。

3.4.bean的实例化

bean实例化的过程就是实现bean代理的过程。

我们从bean容器中获取到bean之后(首先该bean一定是单例模式,只有单例模式的bean才会放到容器中,原型模式的bean不会注入容器,原型模式每次获取bean时都会重新获取bean),并不是直接使用该bean,而且使用该bean的代理类,这样在对bean做操作时不会影响容器中的bean。

Spring实例化过程:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
    //实例化bean方法
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		//...省略
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
                //调用代理实现
				return instantiateBean(beanName, mbd);
			}
		}
        //...省略
		//调用代理实现
		return instantiateBean(beanName, mbd);
	}
}
复制代码

实例化的具体操作需要调用到代理中进行实现,Spring中实现代理的方式有两种,分别是SimpleInstantiationStrategyCglibSubclassingInstantiationStrategy,两种实现分别代表两种不同的策略,当然可以自己对InstantiationStrategy接口自我扩展。

//默认代理策略
public class SimpleInstantiationStrategy implements InstantiationStrategy {

    
	@Override
	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		if (!bd.hasMethodOverrides()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(
									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
						}
						else {
							constructorToUse = clazz.getDeclaredConstructor();
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// 如果类被覆盖,则使用CGlib方式获取代理类
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}
}




//CGlib的方式生成代理类
public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {
		public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
			//通过Enhancer方式创建代理类
			Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
			Object instance;
			if (ctor == null) {
				instance = BeanUtils.instantiateClass(subclass);
			}
			else {
				try {
					Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
					instance = enhancedSubclassConstructor.newInstance(args);
				}
				catch (Exception ex) {
					throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
							"Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
				}
			}
			// SPR-10785: set callbacks directly on the instance instead of in the
			// enhanced class (via the Enhancer) in order to avoid memory leaks.
			Factory factory = (Factory) instance;
			factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
					new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
					new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
			return instance;
		}
		
		//CGlib方式创建代理类
		private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
			Enhancer enhancer = new Enhancer();
			//设置代理类
			enhancer.setSuperclass(beanDefinition.getBeanClass());
			enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
			if (this.owner instanceof ConfigurableBeanFactory) {
				ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
				enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
			}
			enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
			enhancer.setCallbackTypes(CALLBACK_TYPES);
			return enhancer.createClass();
		}
}
复制代码

3.5.循环依赖的处理

bean实例化之后,后续需要进行属性注入,但是在属性注入时涉及bean的循环依赖问题,Spring通过三级缓存解决循环依赖问题,bean生命周期中在属性注入前置做了处理循环依赖的逻辑。

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
  	//三级缓存处理循环依赖:singletonObjects-一级缓存,earlySingletonObjects-二级缓存,singletonFactories-三级缓存
	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
        //对以及缓存加锁
		synchronized (this.singletonObjects) {
            //判断一级缓存中是否存在该bean,不存在则将该bean放入三级缓存,同时移除二级缓存的bean
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
			}
		}
	}
}
复制代码

三级缓存的实现如下:

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// 调用getSingleton方法,singleton方法中实现了三级缓存的操作
		Object sharedInstance = getSingleton(beanName);
        //...省略
    }
}



public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
	//一级缓存
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

	//三级缓存
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);

	//二级缓存
	private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    
    //调用该方法时,首先从一级缓存中获取,如果一级缓存中不存在,则从二级缓存中获取,如果二级缓存中不存在
    //则从三级缓存中获取,三级缓存存在时,则将该bean放入二级缓存。同时从三级缓存中移除。
	@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //一级缓存获取bean
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
                //二级缓存获取bean
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
                    //三级缓存获取bean
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
						this.earlySingletonObjects.put(beanName, singletonObject);
						this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return singletonObject;
	}
}
复制代码

所以三级缓存逻辑为:

3.6.BeanPostProcessor的处理

前面完成了三级缓存,后续需要进行属性填充,但是属性填充前还需要对BeanPostProcessor做处理。

BeanPostProcessor接口是暴露给用户进行对bean对象的扩展的接口,该接口中可以实现对bean初始化的前置和后置的处理,比如前置中可以自我扩展bean属性,以及修改bean属性等操作。

而BeanPostProcessor对bean做的操作,在Spring中做了逻辑处理,该逻辑是在属性填充前进行的。主要逻辑如下:

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		//...省略
		PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
		//...省略
		PropertyDescriptor[] filteredPds = null;
		if (hasInstAwareBpps) {
			if (pvs == null) {
				pvs = mbd.getPropertyValues();
			}
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
					PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						if (filteredPds == null) {
							filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
						}
                        //处理beanPostProcessor对bean的操作
						pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
						if (pvsToUse == null) {
							return;
						}
					}
					pvs = pvsToUse;
				}
			}
		}
		//...省略
		if (pvs != null) {
            //对bean填充属性
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}
复制代码

所以平时我们在一些接口中实现BeanPostProcessor接口,同时做具体实现对bean的属性进行修改时,那么该修改就在此处完成对bean的修改。例如:

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if ("userService".equals(beanName)) {
            UserService userService = (UserService) bean;
            userService.setToken("修改后的属性值");
        }
        return bean;
    }
    
}
复制代码

3.7.bean属性填充

循环依赖问题处理结束,那么后续要做的就是完成bean属性的填充,对于这个填充简单理解就是一个class类的属性值的设置,在Spring中会对这个操作进行单独处理,主要的核心代码如下:

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
            //bean实例化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		//...省略
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
            //处理三级循环
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
            //设置bean属性
			populateBean(beanName, mbd, instanceWrapper);
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
    	//...省略
	}
复制代码

以上代码是Spring生命周期的过程,填充bean属性的逻辑封装在populateBean中。下面看populateBean中封装的逻辑。

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		//...省略
		if (pvs != null) {
            //对bean填充属性
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}
复制代码

其中applyPropertyValues中主要封装的是遍历PropertyValues,然后将PropertyValue设置到bean中。

protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
		//...省略
		List<PropertyValue> original;

		if (pvs instanceof MutablePropertyValues) {
			//...省略
			original = mpvs.getPropertyValueList();
		}
		else {
			original = Arrays.asList(pvs.getPropertyValues());
		}

		TypeConverter converter = getCustomTypeConverter();
		if (converter == null) {
			converter = bw;
		}
		BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

		// 初始化一个List<PropertyValue>,用于后续给BeanWrapper赋值
		List<PropertyValue> deepCopy = new ArrayList<>(original.size());
		boolean resolveNecessary = false;
    	//遍历List<PropertyValue>,然后将PropertyValue设置到BeanWrapper中
		for (PropertyValue pv : original) {
			if (pv.isConverted()) {
				deepCopy.add(pv);
			}
			else {
				//...省略
				if (resolvedValue == originalValue) {
					if (convertible) {
						pv.setConvertedValue(convertedValue);
					}
					deepCopy.add(pv);
				}
				else if (convertible && originalValue instanceof TypedStringValue &&
						!((TypedStringValue) originalValue).isDynamic() &&
						!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
					pv.setConvertedValue(convertedValue);
					deepCopy.add(pv);
				}
				else {
					resolveNecessary = true;
					deepCopy.add(new PropertyValue(pv, convertedValue));
				}
			}
		}
		if (mpvs != null && !resolveNecessary) {
			mpvs.setConverted();
		}

		// Set our (possibly massaged) deep copy.
		try {
            //将List<PropertyValue>的数据通过deepCopy赋值给BeanWrapper中
			bw.setPropertyValues(new MutablePropertyValues(deepCopy));
		}
		catch (BeansException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Error setting property values", ex);
		}
	}
复制代码

以上代码就完成了对bean对象的属性赋值,通过该逻辑将初始化在xml中的属性填充到bean对象中,或者通过注解的方式将属性填充到bean中。

3.8.bean的初始化

到这里所有的准备工作都做完了,接下来就是最后的一步,bean的初始化,bean的初始化简单来说就是执行初始化的方法,以及生成最终的bean,这个bean就是用来放到一级容器的bean,也就是通过getBean获取到的bean对象。核心逻辑如下:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
    //bean初始化时调用该方法
	protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			//处理xxxAware的逻辑,比如BeanFactoryAware、BeanNameAware等
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            //执行beanPostProcessorBefore逻辑
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
            //执行初始化的方法
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
            //执行beanPostProcessorAfter逻辑
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		//返回需要放入容器的bean
		return wrappedBean;
	}
}
复制代码

以上代码就完成bean初始化的操作,该操作中主要的核心是invokeInitMethods以及applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization,这两个方法就是我们平时使用BeanPostProcessor接口实现类时对bean做操作。

整个逻辑梳理下来,对bean的生命周期也有了清晰的认识。

3.9.bean的后置销毁处理

bean完成使用之后需要对bean进行销毁,在Spring中销毁bean的方式有多种,最常用的应该就是实现DisposableBean接口,对bean进行销毁,如果容器关闭,那么会直接销毁该bean。那么这种方式是如何对bean进行销毁的呢?

首先销毁逻辑在DisposableBeanAdapter进行了封装,通过调用#run或者#destroy方法进行销毁。真实情况是调用destroy,过程如下:

xxxBean实现DisposableBean,Spring通过registerDisposableBeanIfNecessary将实现了DisposableBean的bean放入disposableBeans容器,容器关闭时调用destroySingleton,该方法中移除disposableBeans容器的指定bean,然后执行destroyBean方法,该方法中调用DisposableBean#destroy方法,该方法的实现最终在DisposableBeanAdapter#destroy进行处理销毁bean的逻辑。

class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable {
    
    @Override
	public void run() {
		destroy();
	}

    
	@Override
	public void destroy() {
		if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
			for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
                //通过postprocessor的方式调用销毁bean的方法,该方式下如果使用注解PreDestroy销毁bean,					//则会调用到此处进行bean的销毁
				processor.postProcessBeforeDestruction(this.bean, this.beanName);
			}
		}
		if (this.invokeDisposableBean) {
			try {
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> 						{	
                        //调用DisposableBean的destroy方法销毁bean
						((DisposableBean) this.bean).destroy();
						return null;
					}, this.acc);
				}
				else {
                    ////调用DisposableBean的destroy方法销毁bean
					((DisposableBean) this.bean).destroy();
				}
			}
            //...省略
		}
		//判断destroyMethod是否为null,该方法的判断是通过xml配置文件中的destroy-method属性进行制定的销		 //毁方法
		if (this.destroyMethod != null) {
            //执行自我实现的销毁方法
			invokeCustomDestroyMethod(this.destroyMethod);
		}
		else if (this.destroyMethodName != null) {
			Method methodToCall = determineDestroyMethod(this.destroyMethodName);
			if (methodToCall != null) {
				invokeCustomDestroyMethod(methodToCall);
			}
		}
	}
}




public class InitDestroyAnnotationBeanPostProcessor
		implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
    
    //执行bean销毁
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
       //通过findLifecycleMetadata获取需要销毁的bean的列表,
       LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
       try {
           //调用销毁逻辑
          metadata.invokeDestroyMethods(bean, beanName);
       }
       //...省略代码
    }
    
    //执行bean销毁方法
    public void invokeDestroyMethods(Object target, String beanName) throws Throwable {
        Collection<LifecycleElement> checkedDestroyMethods = this.checkedDestroyMethods;
        Collection<LifecycleElement> destroyMethodsToUse =
            (checkedDestroyMethods != null ? checkedDestroyMethods : this.destroyMethods);
        if (!destroyMethodsToUse.isEmpty()) {
            //遍历LifecycleElement,执行销毁的方法
            for (LifecycleElement element : destroyMethodsToUse) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Invoking destroy method on bean '" + beanName + "': " + element.getMethod());
                }
                //执行销毁方法
                element.invoke(target);
            }
        }
    }

}
复制代码

4.总结

以上完成了对Spring中bean的生命周期的源码梳理,从起始到死亡的过程,该过程只摘录核心代码,具体代码需要通过源码进行梳理,核心代码只用来梳理过程。

该文章用时一周进行完成,校验其中的逻辑代码逻辑。

猜你喜欢

转载自juejin.im/post/7041110366058709029