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中实现代理的方式有两种,分别是 SimpleInstantiationStrategy 和 CglibSubclassingInstantiationStrategy ,两种实现分别代表两种不同的策略,当然可以自己对 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的生命周期的源码梳理,从起始到死亡的过程,该过程只摘录核心代码,具体代码需要通过源码进行梳理,核心代码只用来梳理过程。
该文章用时一周进行完成,校验其中的逻辑代码逻辑。
作者:陈汤姆
原文 :从Spring源码分析Bean的生命周期 - 掘金