上回说到阶段9,现在我们接着往下说
阶段10:所有单例bean初始化完成后阶段
所有单例bean实例化完成之后,spring会回调下面这个接口:
java">package org.springframework.beans.factory;public interface SmartInitializingSingleton {public void afterSingletonsInstantiated();
}
调用逻辑在下面这个方法中
java">/**
* 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton 的bean,调用他们的 afterSingletonsInstantiated 方法。
来个案例
java">package com.shiguiwu.springmybatis.spring.lifecycle.allbeaninit;import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** @description: 10所有bean初始化完成* 注意是非懒加载的bean初始化完成* @author: stone* @date: Created by 2021/3/28 13:35* @version: 1.0.0* @pakeage: com.shiguiwu.springmybatis.spring.lifecycle.allbeaninit*/
@ComponentScan
public class AllBeanInitTests {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// Arrays.stream(context.getBeanDefinitionNames()).forEach(b -> System.out.println(context.getBean(b)));context.register(AllBeanInitTests.class);System.out.println("开始启动容器!");context.refresh();System.out.println("容器启动完毕!");}
}
打印结果
java">开始启动容器!
14:00:04.770 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@11438d26
14:00:04.903 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'
14:00:05.473 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [G:\workspace\ideaWorkspace\spring-mybatis\target\classes\com\shiguiwu\springmybatis\spring\lifecycle\allbeaninit\Bean1.class]
14:00:05.474 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [G:\workspace\ideaWorkspace\spring-mybatis\target\classes\com\shiguiwu\springmybatis\spring\lifecycle\allbeaninit\Bean2.class]
14:00:05.483 [main] DEBUG org.springframework.context.annotation.ClassPathBeanDefinitionScanner - Identified candidate component class: file [G:\workspace\ideaWorkspace\spring-mybatis\target\classes\com\shiguiwu\springmybatis\spring\lifecycle\allbeaninit\MySmartInitializingSingleton.class]
14:00:05.571 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerProcessor'
14:00:05.586 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory'
14:00:05.588 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalAutowiredAnnotationProcessor'
14:00:05.591 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'org.springframework.context.annotation.internalCommonAnnotationProcessor'
14:00:05.673 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'allBeanInitTests'
14:00:05.683 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean1'
14:00:05.683 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'bean2'
14:00:05.684 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'mySmartInitializingSingleton'
SmartInitializingSingleton#afterSingletonsInstantiated========================
容器启动完毕!
阶段11:Bean使用阶段
这个阶段就不说了,调用getBean方法得到了bean之后,大家可以随意使用,任意发挥。
阶段12:Bean销毁阶段
触发bean销毁的几种方式
- 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
- 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
- 调用ApplicationContext中的close方法
Bean销毁阶段会依次执行
- 轮询beanPostProcessors列表,如果DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法
- 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法
- 调用bean自定义的销毁方法
DestructionAwareBeanPostProcessor 接口
java">package org.springframework.beans.factory.config;import org.springframework.beans.BeansException;public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {//bean销毁前调用的方法void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;//用来判断bean是否需要触发postProcessBeforeDestruction方法default boolean requiresDestruction(Object bean) {return true;}
}
这个接口有个关键的实现类:
java">org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor#postProcessBeforeDestruction方法中会调用bean中所有标注了@PreDestroy的方法。
再来说一下自定义销毁方法有3种方式
方式1:xml中指定销毁方法
<bean destroy-method="bean中方法名称"/>
方式2:@Bean中指定销毁方法
java">@Bean(destroyMethod = "初始化的方法")
方式3:api的方式指定销毁方法
this.beanDefinition.setDestroyMethodName(methodName);
初始化方法最终会赋值给下面这个字段
java">org.springframework.beans.factory.support.AbstractBeanDefinition#destroyMethodName
来个案例
java">package com.shiguiwu.springmybatis.spring.lifecycle.destroy;import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;/*** @description: 销毁时调用的代码* @author: stone* @date: Created by 2021/3/28 14:55* @version: 1.0.0* @pakeage: com.shiguiwu.springmybatis.spring.lifecycle.destroy*/
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {@Overridepublic void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {System.out.println("准备销毁bean:" + beanName);}@Overridepublic boolean requiresDestruction(Object bean) {System.out.println("是否调用。。。。。。。");return true;}
}
测试代码
java">package com.shiguiwu.springmybatis.spring.lifecycle.destroy;import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;/*** @description: 12销毁阶段** 1. 调用* org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyB* ean* 2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons* 3. 调用ApplicationContext中的close方法** 顺序* 1. @PreDestroy标注的所有方法* 2. DisposableBean接口中的destroy()* 3. 自定义的销毁方法* @author: stone* @date: Created by 2021/3/28 13:59* @version: 1.0.0* @pakeage: com.shiguiwu.springmybatis.spring.lifecycle.destroy*/
public class DestroyTests {public static void main(String[] args) {DefaultListableBeanFactory factory = new DefaultListableBeanFactory();factory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());//将CommonAnnotationBeanPostProcessor加入factory.addBeanPostProcessor(new CommonAnnotationBeanPostProcessor()); //@2AbstractBeanDefinition definition = BeanDefinitionBuilder.genericBeanDefinition(Integer.class).addConstructorArgValue(12).getBeanDefinition();AbstractBeanDefinition definition1 = BeanDefinitionBuilder.genericBeanDefinition(Integer.class).addConstructorArgValue(12).getBeanDefinition();AbstractBeanDefinition definition3 = BeanDefinitionBuilder.genericBeanDefinition(A.class).getBeanDefinition();//设置销毁方法definition3.setDestroyMethodName("destroy1");factory.registerBeanDefinition("shuzi", definition);factory.registerBeanDefinition("shuzi1", definition1);factory.registerBeanDefinition("A", definition3);//触发所有单列初始化factory.preInstantiateSingletons();//销毁一个factory.destroySingleton("shuzi");System.out.println("销毁所有的bean");factory.destroySingletons();//关闭容器}
}
打印结果
java">14:29:38.611 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'shuzi'
是否调用。。。。。。。
是否调用。。。。。。。
14:29:38.922 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'shuzi1'
是否调用。。。。。。。
是否调用。。。。。。。
14:29:38.923 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'A'
是否调用。。。。。。。
准备销毁bean:shuzi
销毁所有的bean
准备销毁bean:A
preDestroy()
destroy()
destroy1() 自定义的。。。。。。。。
准备销毁bean:shuzi1
实际上ApplicationContext内部已经将spring内部一些常见的必须的 BeannPostProcessor 自动装配到beanPostProcessors列表中 ,比如我们熟悉的下面的几个
1.org.springframework.context.annotation.CommonAnnotationBeanPostProcessor用来处理@Resource、@PostConstruct、@PreDestroy的
2.org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor用来处理@Autowired、@Value注解
3.org.springframework.context.support.ApplicationContextAwareProcessor
用来回调Bean实现的各种Aware接口
下面来说一个非常非常重要的类,打起精神,一定要注意看。
AbstractApplicationContext类(非常重要的类)
BeanFactory接口
这个我们已经很熟悉了,Bean工厂的顶层接口
DefaultListableBeanFactory类
实现了BeanFactory接口,可以说这个可以是BeanFactory接口真正的唯一实现,内部真正实现了bean生命周期中的所有代码。其他的一些类都是依赖于DefaultListableBeanFactory类,将请求转发给DefaultListableBeanFactory进行bean的处理的。
其他3个类
我们经常用到的就是这3个类:
AnnotationConfigApplicationContext/ClassPathXmlApplicationContext/FileSystemXmlApplicationContext这3个类,他们的主要内部的功能是依赖他的父类AbstractApplicationContext来实现的,所以大家主要看AbstractApplicationContext 这个类。
AbstractApplicationContext类
这个类中有2个比较重要的方法
java">public abstract ConfigurableListableBeanFactory getBeanFactory() throws
IllegalStateException;
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory
beanFactory)
大家是否注意过我们使用 AnnotationConfigApplicationContext 的时候,经常调用 refresh方法 ,这个方法内部就会调用上面这2个方法
第一个方法:getBeanFactory()
返回当前应用上下文中的 ConfigurableListableBeanFactory ,这也是个接口类型的,这个接口有一个唯一的实现类: DefaultListableBeanFactory 。有没有很熟悉,上面说过:DefaultListableBeanFactory是BeanFactory真正的唯一实现。应用上线文中就会使用这个 ConfigurableListableBeanFactory 来操作spring容器。
第二个方法:registerBeanPostProcessors
说的通俗点:这个方法就是向ConfigurableListableBeanFactory中注册BeanPostProcessor,内容会从spring容器中获取所有类型的BeanPostProcessor,将其添加到DefaultListableBeanFactory#beanPostProcessors列表中
看一下这个方法的源码:
java">protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
会将请求转发给PostProcessorRegistrationDelegate#registerBeanPostProcessors 。内部比较长,大家可以去看一下源码,这个方法内部主要用到了4个BeanPostProcessor 类型的List集合。
List priorityOrderedPostProcessors = new ArrayList<>();
List orderedPostProcessors
List nonOrderedPostProcessors;
List internalPostProcessors = new ArrayList<>();
先说一下:当到方法的时候,spring容器中已经完成了所有Bean的注册。
spring会从容器中找出所有类型的BeanPostProcessor列表,然后按照下面的规则将其分别放到上面的4个集合中,上面4个集合中的 BeanPostProcessor 会被依次添加到DefaultListableBeanFactory#beanPostProcessors列表中,来看一下4个集合的分别放的是那些BeanPostProcessor
priorityOrderedPostProcessors(指定优先级的BeanPostProcessor)
实现org.springframework.core.PriorityOrdered接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的
orderedPostProcessors(指定了顺序的BeanPostProcessor)
实现了org.springframework.core.annotation.Order接口的BeanPostProcessor,但是不包含MergedBeanDefinitionPostProcessor类型的
nonOrderedPostProcessors(未指定顺序的BeanPostProcessor)
上面2中类型置为以及MergedBeanDefinitionPostProcessor之外的internalPostProcessors
MergedBeanDefinitionPostProcessor类型的BeanPostProcessor列表。
大家可以去看一下 CommonAnnotationBeanPostProcessor 和
AutowiredAnnotationBeanPostProcessor ,这两个类都实现了 PriorityOrdered 接口,但是他们也实现了MergedBeanDefinitionPostProcessor 接口,所以最终他们会被丢到
internalPostProcessors 这个集合中,会被放入BeanPostProcessor的最后面。
此致,spring bean生命周期完整的流程结束,附上完整的流程图!!完结,我好累