Spring生命周期简单示例以及重要源码阅读

前言

大家新年好,最近小编比较偷懒,这边首先祝大家牛年大吉大利,财源滚滚!咱们闲话少叙,进入正题,今天和大家分享一下小编理解的spring bean的生命周期。其实对于spring bean的生命周期小编一直无法全面理解,小编认为无非就是创建,使用,销毁,无法到达真正的点上,这次小编借鉴网络大神,然后自己看了相关源代码来理解其中含义,不一定能讲全面,希望对自己有所提升吧。对于时间较少的朋友可以直接看结论

问题

一个Spring Bean是Java对象吗?那么一个对象是Spring Bean吗?
首先小编编写一下代码:
任意一个类,被spring容器所扫描到的

@Service
public class WhateverClass {
}

编写测试类:

@ComponentScan(basePackages = "com.dtyunxi.yundt.life")
public class BeanLifeCycle {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(BeanLifeCycle.class);

        WhateverClass bean = applicationContext.getBean(WhateverClass.class);
        WhateverClass whateverClass = new WhateverClass();

    }
}

这个两个WhateverClass 类的实例对象,一个是被spring容器管理而另一个是咱们自己new出来的。那么他们都是被jvm所加载的。那么以上的问题就有答案了。 SpringBean一定是一个java对象;但是一个Java对象却不一定是一个SpringBean! 那么被spring所管理的对象是spring bean。

猜想

那么一个类如何成为spring bean?假如小编去设计spring那应该怎样做,让spring去管理一个一个类并且初始化还得进行属性填充等等。我们大致分为,扫描相应的类,然后通过类反射生成对象,之后属性填充,如果设置Aop功能还得实现相应的切面逻辑。做完这些保存进去,那么什么比较合适呢,当然Map容器最为合适了。自己实现看起来,整个流程就很清晰,扫描、创建、注入、代理、保存一应俱全,但是Spring的实现方式远比我们自己实现的要复杂的多得多!

结论

这边小编直接写出spring bean的生命周期流程,然后进行源码解读一步一步分析下去。

  1. 扫描项目,将项目指定目录下的Class文件转换为Class对象!
  2. 读取Class对象属性包装为BeanDefinition,然后保存再一个Map中!即BeanDefinitonMap,主要为后期创建对象时更为方便的拿到这个类所需要的信息。
  3. 将全部的类转化为 BeanDefinition 并保存之后,开始调用第一个回调接口BeanFactoryPostProcessor#postProcessBeanFactory()! 即AbstractApplicationContext#refresh()方法中的registerBeanPostProcessors(beanFactory);这个小编在前几篇博客中有详细的讲解,感兴趣的同学可以看一下,主要是spring的扩展以及可用修改已经扫描进去的beanDefiniton。
  4. 先从当前的容器对象取当前要创建的对象,当取出来的对象为null时开始着手创建对象!
  5. 做一系列的验证,比如验证这个类是否被排除、是否正在创建中、是否有依赖Bean【@DependsOn】注解、是否时单例等等!
  6. 验证通过之后,开始通过反射创建这个对象!
  7. 合并BeanDefinition ,这里涉及到Spring之前版本使用的父子容器的概念(忽略)
  8. 判断当前对象是不是单例、是不是支持循环引用、是不是正在创建等!
  9. 执行第二个接口回调InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation()方法!它的执行时机是实例化完成之后,属性填充之前,它的返回值是一个布尔值,当返回false时,不做自动属性填充!
  10. 执行第三个接口回调InstantiationAwareBeanPostProcessor#postProcessProperties()方法!他的执行时机是,实例化之后,属性填充检查之后,属性填充之前!它会返回一个属性,后续的属性填充会使用这个方法返回的值!我们可以在这个方法里面修改对应Bean的注入的值!
  11. 填充属性到对象!
  12. 调用第四个回调接口BeanNameAware#setBeanName()方法!调用时机:属性填充给完毕后,调用初始化方法之前;它的功能是能获取bean的Name!
  13. 调用第五个回调接口BeanClassLoaderAware#setBeanClassLoader()调用时机:BeanNameAware之后,他的功能是传入bean的类加载器;
  14. 调用第六个回调接口BeanFactoryAware#setBeanFactory()!调用时机:BeanClassLoaderAware之后,用于设置beanFactory!
  15. 调用第七个回调接口BeanPostProcessor#postProcessBeforeInitialization()方法调用时机是部分Aware之后,初始化方法之前!传入当前实例化好的对象和beanName,再初始化前做修改!
  16. 回调第八个比较重要的生命周期的初始化方法,它可以是一个InitializingBean接口的bean,也可以是xml中配置的类,也可以是被加了@PostConstruct注解的方法!该方法内部逻辑可以用户自己编写,调用时机为:实例化完成之后调用!
  17. 回调第九个回调接口 BeanPostProcessor#postProcessAfterInitialization()方法!该方法的调用时机为初始化方法执行之后,这里也是Bean实例化后的最后一步,也是SpringAop实现的重要的一步!
  18. 注册销毁方法,以便Spring容器销毁的时候进行方法的销毁!

这里小编不涉及循环依赖,等下一次分享spring循环依赖,当然大前提是spring容器的初始化后才可以进行,上面代码为 new AnnotationConfigApplicationContext()。当然网上好多讲解是从bean的实例化开始的,并没有小编所说的前期扫描等等。
下面画一张流程图帮大家加深印象。
在这里插入图片描述

源码分析

这边由于源码太多了,只挑选比较重要的主要是refresh方法中,然后再给大家列出一个源码结构图即可。
扫描bean

// 调用了beanFactory进行了bean扫描,beanFactory的后置处理
invokeBeanFactoryPostProcessors(beanFactory);

初始化所有剩余的单例对象

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//下面是上面方法的内部方法
beanFactory.preInstantiateSingletons();
public void preInstantiateSingletons() throws BeansException {
		// Trigger initialization of all non-lazy singleton beans...
		for (String beanName : beanNames) {
			//合并beanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				//是否是factoryBean,如果是factoryBean他的名称前面加&
				//之所以加&符号其实放进去的时候名称做了一次转换
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							//最终无论是factoryBean还是普通bean都会调用这个方法
							getBean(beanName);
						}
					}
				}
				else {
					getBean(beanName);
				}
			}
		}
}

最终调用了doGet方法

protected <T> T doGetBean(
			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
			throws BeansException {
		
		String beanName = transformedBeanName(name);
		Object beanInstance;

		// 是否已经有了,第一次肯定没有,这里面会讲到循环依赖也就是spring的三级缓存
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		//否则一系列校验
		else {
			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if bean definition exists in this factory.
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
				else if (args != null) {
					// Delegation to parent with explicit args.
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else if (requiredType != null) {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
				else {
					return (T) parentBeanFactory.getBean(nameToLookup);
				}
			}

			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
					.tag("beanName", name);
			try {
				if (requiredType != null) {
					beanCreation.tag("beanType", requiredType::toString);
				}
				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				String[] dependsOn = mbd.getDependsOn();
				if (dependsOn != null) {
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
						}
						registerDependentBean(dep, beanName);
						try {
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
						}
					}
				}

				// Create bean instance. 目前我们只考虑单例的
				if (mbd.isSingleton()) {
					//真正创建的地方 ,后面的lamba表达式
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					});
					beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}

		return adaptBeanInstance(name, beanInstance, requiredType);
	}

lambda最终调用的方法

Object beanInstance = doCreateBean(beanName, mbdToUse, args);
下面两个是上面方法的子方法
创建实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
属性注入方法
populateBean(beanName, mbd, instanceWrapper);

属性是否属性注入

// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection. 属性注入判断
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}

属性值autowied的处理

for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
					if (pvsToUse == null) {
						return;
					}
				}
				pvs = pvsToUse;
			}

属性值真正注入

if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}

属性注入完毕

exposedObject = initializeBean(beanName, exposedObject, mbd);
//下面是上面方法的实现
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			//无特殊情况肯定会进入这个方法 然后执行awareMethod 看下个代码块
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//执行beanPostProcessor方法的前置回调 注解版本以及其他的aware方法回调
			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()) {
			//执行aop的初始化回调
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

执行aware方法

private void invokeAwareMethods(String beanName, Object bean) {
		if (bean instanceof Aware) {
			//三个aware回调,beanName,beanClassLoader,beaFactory
			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);
			}
		}
	}

源码结构图
在这里插入图片描述

证明代码

@Component
public class SomeClass implements BeanNameAware, ApplicationContextAware, InitializingBean {


    public SomeClass(){
        System.out.println("some class init...");
    }
    @Override
    public void setBeanName(String name) {
        System.out.println("some class bean name aware...");
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        //普通类拿到spring applicationContext方法
        System.out.println("some class application context aware...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("some class life callback from InitializingBean ...");
    }
    @PostConstruct
    public void ruleCallBack(){
        System.out.println("some class life callback from @PostConstruct ...");
    }

    public void  testAop(){

    }
}

aop切面

@Component
@Aspect
public class AopClass {

    @Pointcut("within(com.dtyunxi.yundt.life.SomeClass)")
    public void addJoinPoint(){

    }
    @Before("addJoinPoint()")
    public void addAop(){
        System.out.println("some class Aop before");
    }
}

测试类,开启aop

@ComponentScan(basePackages = "com.dtyunxi.yundt.life")
@EnableAspectJAutoProxy
public class BeanLifeCycle {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext =
                new AnnotationConfigApplicationContext(BeanLifeCycle.class);

        SomeClass bean = applicationContext.getBean(SomeClass.class);
        bean.testAop();


    }
}

打印结果

some class init...
some class bean name aware...
some class application context aware...
some class life callback from @PostConstruct ...
some class life callback from InitializingBean ...
some class Aop before

总结

这篇文章,小编写的并不是怎么好,而且源码非常枯燥,同时无法像自己打断点一样一步一步说明,只希望大家自己也能操作一遍然后就可以更加清晰的理解spring bean的生命周期。最后再次祝大家新年快乐!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木兮君

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值