大纲
Springbean的生命周期总览
- Bean元信息配置阶段
- Bean元信息解析阶段
- 将Bean注册到容器中
- BeanDefinition合并阶段
- Bean Class加载阶段
- Bean实例化阶段(3个小阶段)
- Bean实例化前阶段
- Bean实例化阶段
- 属性赋值阶段(3个小阶段)
- Bean实例化后阶段
- Bean属性赋值前处理
- Bean属性赋值
- Spring Bean Aware接口回调阶段
- Bean属性赋值前阶段
- Spring Bean 初始化阶段
- Bean Aware接口回调
- Bean 初始化前操作
- Bean 初始化操作
- Bean 初始化后操作
- Bean 初始化完成操作
- Spring Bean的使用阶段
- Spring Bean 销毁阶段
- Spring Bean 销毁前阶段
- Spring Bean 销毁阶段
- Spring Bean 垃圾收集
1. Bean元信息配置阶段
参考 注解的方式配置元信息
这一阶段Java程序员通过 XML、Properties、Java注解等形式定义Bean的元信息。
2. Bean元信息解析阶段
元信息解析阶段做的事情是把定义好的Bean元信息解析为BeanDefinition对象。
package bean.beandifinition;
import ioc.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* 注解能力 {@link ApplicationContext} 作为 IoC 容器示例
*
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @since
*/
@Configuration
public class AnnotationBeanDefinitionParseDemo {
public static void main(String[] args) {
// 创建 BeanFactory 容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
// 将当前类 AnnotationApplicationContextAsIoCContainerDemo 作为配置类(Configuration Class)
applicationContext.register(AnnotationBeanDefinitionParseDemo.class);
// 启动应用上下文
applicationContext.refresh();
// 从注解元信息定义形式 解析BeanDefinition
for (String beanName : applicationContext.getBeanDefinitionNames()) {
if(!"xiaomage".equals(beanName)) continue;
BeanDefinition beanDefinition = applicationContext.getBeanDefinition(beanName);
//获取BeanDefinition具体使用的是哪个类
String beanDefinitionClassName = beanDefinition.getClass().getName();
//通过名称获取bean对象
Object bean = applicationContext.getBean(beanName);
//打印输出
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" + beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
// 关闭应用上下文
applicationContext.close();
}
/**
* 通过 Java 注解的方式,定义了一个 Bean
*/
@Bean(name="xiaomage")
public User user() {
User user = new User();
user.setId(1L);
user.setName("小马哥");
return user;
}
}
// 输出
xiaomage:
beanDefinitionClassName:org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader$ConfigurationClassBeanDefinition
beanDefinition:Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=annotationBeanDefinitionParseDemo; factoryMethodName=user; initMethodName=null; destroyMethodName=(inferred); defined in bean.beandifinition.AnnotationBeanDefinitionParseDemo
bean:User{id=1, name='小马哥'}
3. bean的注册阶段: 将Bean注册到容器中
bean注册阶段需要用到一个非常重要的接口:BeanDefinitionRegistry
public interface BeanDefinitionRegistry extends AliasRegistry {
/**
* 注册一个新的bean定义
* beanName:bean的名称
* beanDefinition:bean定义信息
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
/**
* 通过bean名称移除已注册的bean
* beanName:bean名称
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 通过名称获取bean的定义信息
* beanName:bean名称
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
/**
* 查看beanName是否注册过
*/
boolean containsBeanDefinition(String beanName);
/**
* 获取已经定义(注册)的bean名称列表
*/
String[] getBeanDefinitionNames();
/**
* 返回注册器中已注册的bean数量
*/
int getBeanDefinitionCount();
/**
* 确定给定的bean名称或者别名是否已在此注册表中使用
* beanName:可以是bean名称或者bean的别名
*/
boolean isBeanNameInUse(String beanName);
}
BeanDefinitionRegistry有个实现类:DefaultListableBeanFactory
示例代码
//创建一个bean工厂,这个默认实现了BeanDefinitionRegistry接口,所以也是一个bean注册器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//定义一个bean
GenericBeanDefinition nameBdf = new GenericBeanDefinition();
nameBdf.setBeanClass(String.class);
nameBdf.getConstructorArgumentValues().addIndexedArgumentValue(0, "Hello Spring!");
// 注册bean到容器中
factory.registerBeanDefinition("aString", nameBdf);
factory.registerAlias("aString", "bString");
System.out.println(factory.getBean("aString"));
System.out.println(factory.getBean("bString"));
4. BeanDefinition合并阶段
我们定义bean的时候有父子bean关系,此时子BeanDefinition中的信息是不完整的
org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition bean定义可能存在多级父子关系,合并的时候进进行递归合并,最终得到一个包含完整信息的RootBeanDefinition
5. Bean Class加载阶段
BeanDefinition中有个Object类型的字段:beanClass
private volatile Object beanClass;
用来表示bean的class对象,通常这个字段的值有2种类型,一种是bean对应的Class类型的对象,另一种是bean对应的Class的完整类名,第一种情况不需要解析,第二种情况:即这个字段是bean的类名的时候,就需要通过类加载器将其转换为一个Class对象。
6. Bean实例化阶段
6.1 Bean实例化前阶段
// DefaultListableBeanFactory这个类中有个非常非常重要的字段:
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
Bean实例化之前会调用一段代码
// AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInstantiation
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
// postProcessBeforeInstantiation方法默认是空,用户可以覆盖实现来做到直接实例化一个bean实例
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
上面代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor,尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring这里开了一个口子,允许开发者通过这个方法直接创建对象跳过Spring后面的实例化阶段。
public class Test1 {
public static class Car {
private String name;
public Car() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Car{" +
"name='" + name + ''' +
'}';
}
}
@Test
public void test1() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//添加一个BeanPostProcessor:InstantiationAwareBeanPostProcessor
factory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor() { //@1
@Nullable
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("调用postProcessBeforeInstantiation()");
//发现类型是Car类型的时候,硬编码创建一个Car对象返回
if (beanClass == Car.class) {
Car car = new Car();
car.setName("保时捷");
return car;
}
return null;
}
});
//定义一个car bean,车名为:奥迪
AbstractBeanDefinition carBeanDefinition = BeanDefinitionBuilder.
genericBeanDefinition(Car.class).
addPropertyValue("name", "奥迪"). //@2
getBeanDefinition();
factory.registerBeanDefinition("car", carBeanDefinition);
//从容器中获取car这个bean的实例,输出
System.out.println(factory.getBean("car"));
}
}
// 输出
调用postProcessBeforeInstantiation()
Car{name='保时捷'}
6.2 Bean实例化阶段
// AbstractAutowireCapableBeanFactory.determineConstructorsFromBeanPostProcessors
protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
throws BeansException {
if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
if (ctors != null) {
return ctors;
}
}
}
}
return null;
}
这个过程会决定构造器determineCandidateConstructors用于bean的实例化
7 合并后的BeanDefinition处理
// 合并后的BeanDefinition处理源码
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
会调用MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
postProcessMergedBeanDefinition有2个实现类
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存
8 Bean的属性赋值阶段
8.1 实例化后阶段
会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
postProcessAfterInstantiation方法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过了。
8.2 属性赋值前阶段
会调用InstantiationAwareBeanPostProcessor接口的postProcessProperties方法
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
从上面可以看出,如果InstantiationAwareBeanPostProcessor中的postProcessProperties和postProcessPropertyValues都返回空的时候,表示这个bean不需要设置属性,直接返回了,直接进入下一个阶段。
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
PropertyValues中保存了bean实例对象中所有属性值的设置,所以我们可以在这个这个方法中对PropertyValues值进行修改。 修改的方式
// 匿名内部类的方式
factory.addBeanPostProcessor(new InstantiationAwareBeanPostProcessor()
这个方法有2个比较重要的实现类 AutowiredAnnotationBeanPostProcessor在这个方法中对@Autowired、@Value标注的字段、方法注入值。 CommonAnnotationBeanPostProcessor在这个方法中对@Resource标注的字段和方法注入值。
8.3 属性赋值阶段
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。
PropertyValues中的值是通过bean xml中property元素配置的,或者调用MutablePropertyValues中add方法设置的值。
9 Bean初始化阶段
9.1 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);
}
}
}
依次做了下面三个事情
- BeanNameAware:将bean的名称注入进去
- BeanClassLoaderAware:将BeanClassLoader注入进去
- BeanFactoryAware:将BeanFactory注入进去
9.2 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,当前方法将结束。
通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。
这个方法所在接口有两个重要的实现类
org.springframework.context.support.ApplicationContextAwareProcessor
org.springframework.context.annotation.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注解的方法
9.3 Bean初始化操作
2个步骤
- 调用InitializingBean接口的afterPropertiesSet方法
- 调用定义bean的时候指定的初始化方法。
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
当我们的bean实现了这个接口的时候,会在这个阶段被调用bean定义的时候指定的初始化方法。 指定bean的初始化方法的方式
方式1:xml方式指定初始化方法
<bean init-method="bean中方法名称"/>
方式2:@Bean的方式指定初始化方法
@Bean(initMethod = "初始化的方法")
方式3:api的方式指定初始化方法
this.beanDefinition.setInitMethodName(methodName);
初始化方法最终会赋值给下面这个字段
org.springframework.beans.factory.support.AbstractBeanDefinition#initMethodName
9.4 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方法,返回null的时候,会中断上面的操作。
通常称postProcessAfterInitialization这个方法为:bean初始化后置操作。
9.5 Bean初始化完成操作
所有单例bean实例化完成之后,spring会回调下面这个接口
public interface SmartInitializingSingleton {
void afterSingletonsInstantiated();
}
调用逻辑在下面的方法
/**
* 确保所有非lazy的单例都被实例化,同时考虑到FactoryBeans。如果需要,通常在工厂设置结束时调用。
*/
org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton的bean,调用他们的afterSingletonsInstantiated方法。
10 Bean的销毁阶段
触发bean销毁的几种方式
1. 调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#destroyBean
2. 调用org.springframework.beans.factory.config.ConfigurableBeanFactory#destroySingletons
3. 调用ApplicationContext中的close方法
Bean销毁阶段会依次执行
- 轮询beanPostProcessors列表,如果是DestructionAwareBeanPostProcessor这种类型的,会调用其内部的postProcessBeforeDestruction方法。
- 如果bean实现了org.springframework.beans.factory.DisposableBean接口,会调用这个接口中的destroy方法。
- 调用bean自定义的销毁方法
自定义销毁方法有3种方式
- 方式1:xml中指定销毁方法
<bean destroy-method="bean中方法名称"/> - 方式2:@Bean中指定销毁方法
@Bean(destroyMethod = "初始化的方法") - 方式3:api的方式指定销毁方法
this.beanDefinition.setDestroyMethodName(methodName);
初始化方法最终会赋值给下面这个字段 org.springframework.beans.factory.support.AbstractBeanDefinition#destroyMethodName
销毁方法调用的顺序:
- @PreDestroy标注的所有方法
- DisposableBean接口中的destroy()
- 自定义的销毁方法
11 全局视野
BeanFactory接口,Bean工厂的顶层接口, IoC的底层容器。
DefaultListableBeanFactory类 实现了BeanFactory接口,可以说这个可以是BeanFactory接口真正的唯一实现,内部真正实现了bean生命周期中的所有代码。 其他的一些类都是依赖于DefaultListableBeanFactory类,将请求转发给DefaultListableBeanFactory进行bean的处理的。
AbstractApplicationContext类有两个比较重要的方法。
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
我们使用AnnotationConfigApplicationContext的时候,经常调用reflush方法,这个方法内部就会调用上面这2个方法。
-
第一个方法: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容器中已经完成了所有Bean的注册