15.spring系列- bean生命周期-3

阶段9:Bean初始化阶段

分为5个小阶段:

  1. Bean Aware接口回调
  2. Bean初始化前操作
  3. Bean初始化操作
  4. Bean初始化后操作
  5. Bean初始化完成操作

Bean Aware接口回调

private void invokeAwareMethods(final String beanName, final Object bean) {
        if (bean instanceof Aware) {
            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);
            }
        }
    }

如果我们的bean实例实现了上面的接口,会按照下面的顺序依次进行调用:BeanNameAware,BeanClassLoaderAware,BeanFactoryAware

Bean初始化前操作

这个阶段的源码:

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

会调用BeanPostProcessor的postProcessBeforeInitialization方法,若返回null,当前方法将结束。

这个接口有2个实现类,比较重要:ApplicationContextAwareProcessor,CommonAnnotationBeanPostProcessor

ApplicationContextAwareProcessor注入6个Aware接口对象:

如果bean实现了下面的接口,在ApplicationContextAwareProcessor#postProcessBeforeInitialization中会依次调用下面接口中的方法,将Aware前缀对应的对象注入到bean实例中。

  • EnvironmentAware:注入Environment对象
  • EmbeddedValueResolverAware:注入EmbeddedValueResolver对象
  • ResourceLoaderAware:注入ResourceLoader对象
  • ApplicationEventPublisherAware:注入ApplicationEventPublisher对象
  • MessageSourceAware:注入MessageSource对象
  • ApplicationContextAware:注入ApplicationContext对象

CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法

Bean初始化阶段

  1. 调用InitializingBean接口的afterPropertiesSet方法
  2. 调用定义bean的时候指定的初始化方法。

这里说下bean的指定初始化方法:

  1. xml方式 :<bean init-method="bean中方法名称"/>
  2. @Bean方式 @Bean(initMethod = "初始化的方法")
  3. api方式 this.beanDefinition.setInitMethodName(methodName);

案例

public class Color implements InitializingBean {

    Color(){
        System.out.println("无参构造器");
    }

    public void initMethod(){
        System.out.println("initMethod");
    }


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
    }
}

测试方法:

    @Test
    public void testInitMethod() {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("color",
                BeanDefinitionBuilder.genericBeanDefinition(Color.class)
                        .setInitMethodName("initMethod")
                        .getBeanDefinition());
        Object color = factory.getBean("color");
        System.out.println(color);
    }

运行结果:

无参构造器
afterPropertiesSet
initMethod
com.spring.beanlife4.Color@35ef1869

Bean 初始化后阶段

这块的源码:

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

调用BeanPostProcessor接口的postProcessAfterInitialization方法。

阶段10:所有单例bean初始化完成后阶段

所有单例bean实例化完成之后,spring会回调下面这个接口:

public interface SmartInitializingSingleton {
    void afterSingletonsInstantiated();
}

调用逻辑在下面这个方法中

//确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

案例

@Component
public class Yellow {

    Yellow(){
        System.out.println("yellow");
    }
}
@Component
public class Blue {

    Blue(){
        System.out.println("blue");
    }
}
@Component
public class MySmartInitializingSingleton implements SmartInitializingSingleton {

    @Override
    public void afterSingletonsInstantiated() {
        System.out.println("所有的bean初始化完成");
    }
}

测试:

    @Test
    public void testInitAll(){
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ColorConfig.class);
    }

运行结果:

blue
17:46:07.583 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mySmartInitializingSingleton'
17:46:07.585 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'yellow'
yellow
所有的bean初始化完成

案例:使用api的方式

只修改测试方法:

@Test
    public void testInitApi() {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("service1", BeanDefinitionBuilder.genericBeanDefinition(Yellow.class).getBeanDefinition());
        factory.registerBeanDefinition("service2", BeanDefinitionBuilder.genericBeanDefinition(Blue.class).getBeanDefinition());
        factory.registerBeanDefinition("mySmartInitializingSingleton", BeanDefinitionBuilder.genericBeanDefinition(MySmartInitializingSingleton.class).getBeanDefinition());
        //触发所有bean初始化,并且回调 SmartInitializingSingleton#afterSingletonsInstantiated 方法
        factory.preInstantiateSingletons();
    }

运行结果:

yellow
17:48:50.445 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'service2'
blue
17:48:50.446 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mySmartInitializingSingleton'
所有的bean初始化完成

阶段11:Bean 使用阶段

阶段12:Bean销毁阶段

触发bean销毁的几种方式

  1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
  2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
  3. 调用ApplicationContext中的close方法

bean销毁阶段会依次执行

  1. 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
  2. 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
  3. 调用bean自定义的销毁方法

DestructionAwareBeanPostProcessor接口

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

    /**
     * bean销毁前调用的方法
     */
    void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;

    /**
     * 用来判断bean是否需要触发postProcessBeforeDestruction方法
     */
    default boolean requiresDestruction(Object bean) {
        return true;
    }

}

这个接口有个关键的实现类:CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法。

自定义销毁的三种方式:

  1. xml中指定销毁方法 <bean destroy-method="bean中方法名称"/>
  2. @Bean中指定销毁方法 @Bean(destroyMethod = "初始化的方法")
  3. api的方式指定销毁方法 this.beanDefinition.setDestroyMethodName(methodName);

初始化方法最终会赋值给下面这个字段:

AbstractBeanDefinition#destroyMethodName

销毁方法调用的顺序:

  1. @PreDestroy标注的所有方法
  2. DisposableBean接口中的destroy()
  3. 自定义销毁方法

这个我就不写案例了。可以自己百度下。

AbstractApplicationContext

在这里插入图片描述
BeanFactory接口 : Bean工厂的顶层接口

DefaultListableBeanFactory类

实现了BeanFactory接口,可以说这个可以是BeanFactory接口真正的唯一实现,内部真正实现了bean生命周期中的所有代码。

其他的一些类都是依赖于DefaultListableBeanFactory类,将请求转发给DefaultListableBeanFactory进行bean的处理的。

AbstractApplicationContext类

里面有两个重要的方法:

public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)

第一个方法:getBeanFactory()

返回当前应用上下文中的ConfigurableListableBeanFactory,这也是个接口类型的,这个接口有一个唯一的实现类:DefaultListableBeanFactory。

有没有很熟悉,上面说过:DefaultListableBeanFactory是BeanFactory真正的唯一实现。

应用上下文中就会使用这个ConfigurableListableBeanFactory来操作spring容器。

第二个方法:registerBeanPostProcessors

说的通俗点:这个方法就是向ConfigurableListableBeanFactory中注册BeanPostProcessor,内容会从spring容器中获取所有类型的BeanPostProcessor,将其添加到DefaultListableBeanFactory#beanPostProcessors列表中

看一下这个方法的源码:

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

PostProcessorRegistrationDelegate#registerBeanPostProcessors
这个方法内部主要用到了4个BeanPostProcessor类型的List集合。

List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> orderedPostProcessors
List<BeanPostProcessor> nonOrderedPostProcessors;
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();

spring会从容器中找出所有类型的BeanPostProcessor列表,然后按照下面的规则将其分别放到上面的4个集合中,上面4个集合中的BeanPostProcessor会被依次添加到DefaultListableBeanFactory#beanPostProcessors列表中,来看一下4个集合的分别放的是哪些BeanPostProcessor:

priorityOrderedPostProcessors(指定优先级的BeanPostProcessor):

实现org.springframework.core.PriorityOrdered接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的

orderedPostProcessors(指定了顺序的BeanPostProcessor):

标注有@Order注解,或者实现了org.springframework.core.annotation.Order接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的

nonOrderedPostProcessors(未指定顺序的BeanPostProcessor):

上面2种类型以及MergedBeanDefinitionPostProcessor之外的

internalPostProcessors:

MergedBeanDefinitionPostProcessor类型的BeanPostProcessor列表。

Bean生命的流程图:
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值