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