Spring5.0源码深度解析之SpringBean的生命周期

一:单例与多例对象是如何初始化

单例默认情况下是在容器被加载的时候就会初始化 多例是在每次获取Bean对象的时候初始化

代码验证:

@Component
public class UserEntity {
    public UserEntity() {
        System.out.println(">>>>UserEntity无参数构造函数执行...");
    }
@Configuration
@ComponentScan("com.mayikt.entity")
public class MyConfig {
}

>>>>UserEntity无参数构造函数执行...

当加上@Scope("prototype"),没有输出结果

@Component
@Scope("prototype")
public class UserEntity {
    public UserEntity() {
        System.out.println(">>>>UserEntity无参数构造函数执行...");
    }

说明单例默认是在容器被加载的时候初始化,多例是在每次获取Bean对象的时候初始化。

二:Bean对象的初始化与销毁过程01

Bean初始化:指的就是对象已经创建,里面的所有set方法都已经执行完毕了。

举个例子:

@Configuration
@ComponentScan("com.mayikt.entity")
public class MyConfig {

    /**
     * initMethod:指定初始化方法执行
     * destroyMethod:指定销毁方法
     * @return
     */
    @Bean(initMethod = "initMethod",destroyMethod = "destroyMethod")
    public UserEntity userEntity(){
        return new UserEntity();
    }
}
@Component
public class UserEntity {
    public UserEntity() {
        System.out.println(">>>>UserEntity无参数构造函数执行...");
    }
    /**
     * 思考:initMethod是在无参构造函数之前执行还是后执行..
     */
    private void initMethod() {
        System.out.println(">>>>UserEntity initMethod 执行...");
    }
    private void destroyMethod() {
        System.out.println(">>>>UserEntity destroyMethod 执行...");
    }
}
public static void main(String[] args) {
    /**
     * IOC容器初始化单例对象都是循环遍历调用getBean方法
     */
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
    applicationContext.close();

返回结果

>>>>UserEntity无参数构造函数执行... >>>>UserEntity initMethod 执行... >>>>UserEntity destroyMethod 执行...

构造函数:Bean的创建,Map集合存储对象 initMethod:表示对象已经创建成功之后执行 destroyMethod:表示对象被销毁之后执行,clean

分析下源码

applicationContext.close();
public void close() {
   synchronized (this.startupShutdownMonitor) {
      doClose();
      // If we registered a JVM shutdown hook, we don't need it anymore now:
      // We've already explicitly closed the context.
      if (this.shutdownHook != null) {
         try {
            Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
         }
         catch (IllegalStateException ex) {
            // ignore - VM is already shutting down
         }
      }
   }
}
protected void doClose() {
   if (this.active.get() && this.closed.compareAndSet(false, true)) {
      if (logger.isInfoEnabled()) {
         logger.info("Closing " + this);
      }

      LiveBeansView.unregisterApplicationContext(this);

      try {
         // Publish shutdown event.
         publishEvent(new ContextClosedEvent(this));
      }
      catch (Throwable ex) {
         logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex);
      }

      // Stop all Lifecycle beans, to avoid delays during individual destruction.
      try {
         getLifecycleProcessor().onClose();
      }
      catch (Throwable ex) {
         logger.warn("Exception thrown from LifecycleProcessor on context close", ex);
      }

      // Destroy all cached singletons in the context's BeanFactory.
      destroyBeans();

      // Close the state of this context itself.
      closeBeanFactory();

      // Let subclasses do some final clean-up if they wish...
      onClose();

      this.active.set(false);
   }
}
protected void destroyBeans() {
   getBeanFactory().destroySingletons();
}
public void destroySingletons() {
    super.destroySingletons();
    this.manualSingletonNames.clear();
    this.clearByTypeCache();
}
private void clearByTypeCache() {
    this.allBeanNamesByType.clear();
    this.singletonBeanNamesByType.clear();
}

上面执行了clear操作,再回到前面

这里给用户自定义关闭操作:模板方法设计模式

protected void onClose() {
   // For subclasses: do nothing by default.
}

再把活跃状态设置为false。

三:Bean对象的初始化与销毁过程02

实现InitializingBean,DisposableBean两个接口

@Component
public class MemberEntity implements InitializingBean,DisposableBean{
    //     implements InitializingBean, DisposableBean
    public MemberEntity() {
        System.out.println("无参构造函数执行..");
    }
    // afterPropertiesSet initMet hod
    // 1.对象创建 对象属性赋值 set方法全部走完
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("MemberEntity >>>afterPropertiesSet");
    }
    @Override
    public void destroy() throws Exception {
        System.out.println("MemberEntity >>> destroy");
    }
}

输出结果:

无参构造函数执行.. MemberEntity >>>afterPropertiesSet MemberEntity >>> destroy

使用Java封装的注解方式@PostConstruct, @PreDestroy

@Component
public class MemberEntity{
    //     implements InitializingBean, DisposableBean
    public MemberEntity() {
        System.out.println("无参构造函数执行..");
    }
    // afterPropertiesSet initMet hod
    // 1.对象创建 对象属性赋值 set方法全部走完
    @PostConstruct
    public void afterPropertiesSet() throws Exception {
        System.out.println("MemberEntity >>>afterPropertiesSet");
    }
    @PreDestroy
    public void destroy() throws Exception {
        System.out.println("MemberEntity >>> destroy");
    }
}

输出结果

无参构造函数执行.. MemberEntity >>>afterPropertiesSet MemberEntity >>> destroy

四:现在我们开始分析SpringBean的生命周期

SpringBean生命周期有个很好的理念

就是后置处理器:BeanPostProcessor

BeanPostProcessor引入:

@Component
public class MyApplicationContext implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    /**
     * spring底层中为什么能够实现ApplicationContextAware接口 就能够拿到ApplicationContext
     * @param applicationContext
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        MemberEntity memberEntity = applicationContext.getBean("memberEntity", MemberEntity.class);
        System.out.println("memberEntity:" + memberEntity);
    }
}
@Configuration
@ComponentScan("com.mayikt.entity")
@Import(MyApplicationContext.class)//这里注入到spring容器中
public class MyConfig {}

输出结果:对象初始化,赋值完毕,就可以通过setApplicationContext拿到bean对象

memberEntity:com.mayikt.entity.MemberEntity@11e21d0e

思考问题:spring底层中为什么能够实现ApplicationContextAware接口 就能够拿到ApplicationContext

靠的就是:BeanPostProcessor

下面开始分析:BeanPostProcessor后置处理器(非常重要!!!)

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
public void refresh() throws BeansException, IllegalStateException {
   synchronized (this.startupShutdownMonitor) {
    ....
      try {
      ....
         // Instantiate all remaining (non-lazy-init) singletons.
         finishBeanFactoryInitialization(beanFactory);//这里
      }
....
}
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
 ....
   // Instantiate all remaining (non-lazy-init) singletons.
   beanFactory.preInstantiateSingletons();//这里
}
public void preInstantiateSingletons() throws BeansException {
    List<String> beanNames = new ArrayList(this.beanDefinitionNames);
    Iterator var2 = beanNames.iterator();

    while(true) {
        while(true) {
            String beanName;
            RootBeanDefinition bd;
            do {
                do {
                    do {
                        if (!var2.hasNext()) {
                            var2 = beanNames.iterator();

                            while(var2.hasNext()) {
                                beanName = (String)var2.next();
                                Object singletonInstance = this.getSingleton(beanName);
                                if (singletonInstance instanceof SmartInitializingSingleton) {
                                    SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton)singletonInstance;
                                    if (System.getSecurityManager() != null) {
                                        AccessController.doPrivileged(() -> {
                                            smartSingleton.afterSingletonsInstantiated();
                                            return null;
                                        }, this.getAccessControlContext());
                                    } else {
                                        smartSingleton.afterSingletonsInstantiated();
                                    }
                                }
                            }

                            return;
                        }

                        beanName = (String)var2.next();
                        bd = this.getMergedLocalBeanDefinition(beanName);
                    } while(bd.isAbstract());
                } while(!bd.isSingleton());
            } while(bd.isLazyInit());

            if (this.isFactoryBean(beanName)) {
                FactoryBean<?> factory = (FactoryBean)this.getBean("&" + beanName);
                boolean isEagerInit;
                if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                    isEagerInit = (Boolean)AccessController.doPrivileged(() -> {
                        return ((SmartFactoryBean)factory).isEagerInit();
                    }, this.getAccessControlContext());
                } else {
                    isEagerInit = factory instanceof SmartFactoryBean && ((SmartFactoryBean)factory).isEagerInit();
                }

                if (isEagerInit) {
                    this.getBean(beanName);
                }
            } else {
                this.getBean(beanName);
            }
        }
    }
}
public Object getBean(String name) throws BeansException {
    return this.doGetBean(name, (Class)null, (Object[])null, false);
}
Object sharedInstance = this.getSingleton(beanName);//查找缓存中有没有

判断是单例:

this.populateBean(beanName, mbd, instanceWrapper);//循环给属性赋值
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged(() -> {
            this.invokeAwareMethods(beanName, bean);
            return null;
        }, this.getAccessControlContext());
    } else {
        this.invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
    }

    try {
        this.invokeInitMethods(beanName, wrappedBean, mbd);//执行自定义的init方法
    } catch (Throwable var6) {
        throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
    }

    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}
private void invokeAwareMethods(String beanName, Object bean) {
    if (bean instanceof Aware) {
        if (bean instanceof BeanNameAware) {    //判断类型并设置beanName
            ((BeanNameAware)bean).setBeanName(beanName);
        }

        if (bean instanceof BeanClassLoaderAware) {
            ClassLoader bcl = this.getBeanClassLoader();
            if (bcl != null) {
                ((BeanClassLoaderAware)bean).setBeanClassLoader(bcl);
            }
        }

        if (bean instanceof BeanFactoryAware) {
            ((BeanFactoryAware)bean).setBeanFactory(this);
        }
    }
}

我们就明白了:IOC容器初始化单例对象都是循环遍历调用getBean方法。

下面我们手写看下springBean的生命周期

@Component
public class PayEntity implements BeanNameAware, BeanFactoryAware, InitializingBean, ApplicationContextAware {
    public PayEntity() {
        System.out.println("1.对象的实例化完成..");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("2.对象beanName:" + name);
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("3.beanFactory:" + beanFactory);
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("4.获取到applicationContext对象");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("5.bean init方法执行..");
    }

输出结果

1.对象的实例化完成..
2.对象beanName:payEntity
3.beanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@55f3ddb1: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,myConfig,payEntity]; root of factory hierarchy
4.获取到applicationContext对象
5.bean init方法执行..

BeanPostProcessor的作用

if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);//init之前处理操作
    }
    try {
        this.invokeInitMethods(beanName, wrappedBean, mbd);//init执行逻辑
    } catch (Throwable var6) {
        throw new BeanCreationException(mbd != null ? mbd.getResourceDescription() : null, beanName, "Invocation of init method failed", var6);
    }

    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);//init之后处理操作
    }

    return wrappedBean;
}

我们自己写个类实现BeanPostProcessor

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    //BeanPostProcessor 后置处理器 对我们bean的对象实现增强
    @Override
    // 执行自定义init方法之前处理
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行init方法之前处理 : " + beanName);
        return bean;
    }

    @Override
    // 执行自定义init方法之后处理
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行init方法之后处理 :" + beanName);
        return bean;
    }
    //BeanPostProcessor  后置处理
    // Aware    实现
}

结果

执行init方法之前处理 : org.springframework.context.event.internalEventListenerProcessor
执行init方法之后处理 :org.springframework.context.event.internalEventListenerProcessor
执行init方法之前处理 : org.springframework.context.event.internalEventListenerFactory
执行init方法之后处理 :org.springframework.context.event.internalEventListenerFactory
执行init方法之前处理 : myConfig
执行init方法之后处理 :myConfig
1.对象的实例化完成..
2.对象beanName:payEntity
3.beanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@55f3ddb1: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,myConfig,payEntity,com.mayikt.processor.MyBeanPostProcessor]; root of factory hierarchy
4.获取到applicationContext对象
执行init方法之前处理 : payEntity
5.bean init方法执行..
执行init方法之后处理 :payEntity

ApplicationAware接口原理

实现ApplicationAware接口怎么就可以setApplicationContext呢?

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    System.out.println("4.获取到applicationContext对象");
}

去后置处理器找

default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
   return bean;
}

发现postProcessAfterInitialization没有做什么,再去前置找:

private void invokeAwareInterfaces(Object bean) {
   if (bean instanceof Aware) {
      if (bean instanceof EnvironmentAware) {
         ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
      }
      if (bean instanceof EmbeddedValueResolverAware) {
         ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
      }
      if (bean instanceof ResourceLoaderAware) {
         ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
      }
      if (bean instanceof ApplicationEventPublisherAware) {
         ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
      }
      if (bean instanceof MessageSourceAware) {
         ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
      }
      if (bean instanceof ApplicationContextAware) {//判断ApplicationContextAware类型,赋值
         ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
      }
   }
}

所以我们知道ApplicationContextAware是通过前置实现的。

SpringBean的生命周期总结

源码分析流程:

1、执行refresh()刷新方法 2、finishBeanFactoryInitialization(beanFactory); 3、beanFactory.preInstantiateSingletons(); 4、getBean(beanName)->doGetBean()->createBean()->doCreateBean()->createBeanInstance()初始化对象(默认情况下使用Java反射机制初始化对象,也可以通过CGLIB) 5、initializeBean() 6、invokeAwareMethods()判断是否有Aware接口依赖信息 7、applyBeanPostProcessorsBeforeInitialization()执行前置处理 8、invokeInitMethods()执行init()方法 8、applyBeanPostProcessorsAfterInitialization()执行后置处理

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券