Spring bean生命周期
- 阶段1:Bean元信息配置阶段
- 阶段2:Bean元信息解析阶段
- 阶段3:将Bean注册到容器中
- 阶段4:BeanDefinition合并阶段
- 阶段5:Bean Class加载阶段
- 阶段6:Bean实例化阶段
- 阶段7:合并后的BeanDefinition处理
- 阶段8:属性赋值阶段
- 阶段9:Bean初始化阶段
- 阶段10:所有单例bean初始化完成后阶段
- 阶段11:Bean的使用阶段
- 阶段12:Bean销毁前阶段
- 阶段13:Bean销毁阶段
阶段6分为
- Bean实例化前阶段
- Bean实例化阶段
阶段8分为
- Bean实例化后阶段
- Bean属性赋值前阶段.
- Bean属性赋值阶段
阶段9分为
- Bean Aware接口回调阶段
- Bean初始化前阶段
- Bean初始化阶段
- Bean初始化后阶段
阶段1:Bean元信息配置阶段
Bean信息定义4种方式
主要包括xml,@Bean,properties文件,接口
接口
案例1:组装一个简单的bean
public class Car {
private String name;
//省略get、set、toStirng
}
public class Client {
public static void main(String[] args) {
BeanDefinitionBuilder beanDefinitionBuilder =
BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
System.out.println(beanDefinition);
}
}
输出
Root bean: class [com.example.lurenjia.spring.c22.d1.Car];
scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0;
autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null;
initMethodName=null; destroyMethodName=null
案例2:组装一个有属性的bean
public class Client2 {
public static void main(String[] args) {
BeanDefinitionBuilder beanDefinitionBuilder =
BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
beanDefinitionBuilder.addPropertyValue("name", "奥迪");
BeanDefinition carBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
System.out.println(carBeanDefinition);
System.out.println("----");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("car", carBeanDefinition);
Car bean = factory.getBean("car", Car.class);
System.out.println(bean);
}
}
输出
Root bean: class [com.example.lurenjia.spring.c22.jd1.d1.Car]; scope=; abstract=false; lazyInit=null;
autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null;
factoryMethodName=null; initMethodName=null; destroyMethodName=null
----
Creating shared instance of singleton bean 'car'
Car{name='奥迪'}
案例3:组装一个有依赖关系的bean
public class User {
private String name;
private Car car;
//省略get、set、toStirng
}
public class Client3 {
public static void main(String[] args) {
BeanDefinition carBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName()).addPropertyValue("name", "奥迪").getBeanDefinition();
BeanDefinition userBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName()).
addPropertyValue("name", "路人甲Java").
addPropertyReference("car", "car").
getBeanDefinition();
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("car", carBeanDefinition);
factory.registerBeanDefinition("user", userBeanDefinition);
System.out.println(factory.getBean("car"));
System.out.println(factory.getBean("user"));
}
}
Car{name='奥迪'}
User{name='路人甲Java', car=Car{name='奥迪'}}
案例4:来2个有父子关系的bean
public class Client4 {
public static void main(String[] args) {
BeanDefinition carBeanDefinition1 = BeanDefinitionBuilder.
genericBeanDefinition(Car.class).
addPropertyValue("name", "保时捷").
getBeanDefinition();
BeanDefinition carBeanDefinition2 = BeanDefinitionBuilder.
genericBeanDefinition().
setParentName("car1").
getBeanDefinition();
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("car1", carBeanDefinition1);
factory.registerBeanDefinition("car2", carBeanDefinition2);
System.out.println(String.format("car1->%s", factory.getBean("car1")));
System.out.println(String.format("car2->%s", factory.getBean("car2")));
}
}
car1->Car{name='保时捷'}
car2->Car{name='保时捷'}
案例5:通过api设置(Map、Set、List)属性
public class CompositeObj {
private String name;
private Integer salary;
private Car car1;
private List<String> stringList;
private List<Car> carList;
private Set<String> stringSet;
private Set<Car> carSet;
private java.util.Map<String, String> stringMap;
private java.util.Map<String, Car> stringCarMap;
//省略get set tostring
}
public class Client {
public static void main(String[] args) {
//定义car1
BeanDefinition car1 = BeanDefinitionBuilder.
genericBeanDefinition(Car.class).
addPropertyValue("name", "奥迪").
getBeanDefinition();
//定义car2
BeanDefinition car2 = BeanDefinitionBuilder.
genericBeanDefinition(Car.class).
addPropertyValue("name", "保时捷").
getBeanDefinition();
//定义CompositeObj这个bean
//创建stringList这个属性对应的值
ManagedList<String> stringList = new ManagedList<>();
stringList.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));
//创建carList这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
ManagedList<RuntimeBeanReference> carList = new ManagedList<>();
carList.add(new RuntimeBeanReference("car1"));
carList.add(new RuntimeBeanReference("car2"));
//创建stringList这个属性对应的值
ManagedSet<String> stringSet = new ManagedSet<>();
stringSet.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));
//创建carSet这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
ManagedList<RuntimeBeanReference> carSet = new ManagedList<>();
carSet.add(new RuntimeBeanReference("car1"));
carSet.add(new RuntimeBeanReference("car2"));
//创建stringMap这个属性对应的值
ManagedMap<String, String> stringMap = new ManagedMap<>();
stringMap.put("系列1", "java高并发系列");
stringMap.put("系列2", "Maven高手系列");
stringMap.put("系列3", "mysql系列");
ManagedMap<String, RuntimeBeanReference> stringCarMap = new ManagedMap<>();
stringCarMap.put("car1", new RuntimeBeanReference("car1"));
stringCarMap.put("car2", new RuntimeBeanReference("car2"));
//下面我们使用原生的api来创建BeanDefinition
GenericBeanDefinition compositeObj = new GenericBeanDefinition();
compositeObj.setBeanClassName(CompositeObj.class.getName());
compositeObj.getPropertyValues().add("name", "路人甲Java").
add("salary", 50000).
add("car1", new RuntimeBeanReference("car1")).
add("stringList", stringList).
add("carList", carList).
add("stringSet", stringSet).
add("carSet", carSet).
add("stringMap", stringMap).
add("stringCarMap", stringCarMap);
//将上面bean 注册到容器
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("car1", car1);
factory.registerBeanDefinition("car2", car2);
factory.registerBeanDefinition("compositeObj", compositeObj);
//下面我们将容器中所有的bean输出
for (String beanName : factory.getBeanDefinitionNames()) {
System.out.println(String.format("%s->%s", beanName, factory.getBean(beanName)));
}
}
}
xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloWorld" class="com.example.lurenjia.spring.c3.HelloWorld"/>
</beans>
xml中的bean配置信息会被解析器解析为BeanDefinition对象,一会在第二阶段详解。
properties文件的方式
参照阶段2解析里面properties文件定义内容
注解的方式
类上标注@Compontent注解来定义一个bean
示例省略
配置类中使用@Bean注解来定义bean
示例省略
阶段2:Bean元信息解析阶段
目的:将阶段1各种方式的定义解析为 BeanDefinition 对象
XML方式解析:XmlBeanDefinitionReader
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="helloWorld" class="com.example.lurenjia.spring.c3.HelloWorld"/>
</beans>
public class Client {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
String location = "classpath:beans3.xml";
int countBean = xmlBeanDefinitionReader.loadBeanDefinitions(location);
System.out.println(String.format("共注册了 %s 个bean", countBean));
for (String beanName : factory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
String beanDefinitionClassName = beanDefinition.getClass().getName();
Object bean = factory.getBean(beanName);
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" + beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
}
}
共注册了 1 个bean
helloWorld:
beanDefinitionClassName:org.springframework.beans.factory.support.GenericBeanDefinition
beanDefinition:Generic bean: class [com.example.lurenjia.spring.c3.HelloWorld]; scope=; abstract=false;
lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false;
factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null;
defined in class path resource [beans3.xml]
bean:com.example.lurenjia.spring.c3.HelloWorld@51565ec2
properties文件定义bean的解析:PropertiesBeanDefinitionReader
官方示例
employee.(class)=MyClass // bean is of class MyClass
employee.(abstract)=true // this bean can't be instantiated directly
employee.group=Insurance // real property
employee.usesDialUp=false // real property (potentially overridden)
salesrep.(parent)=employee // derives from "employee" bean definition
salesrep.(lazy-init)=true // lazily initialize this singleton bean
salesrep.manager(ref)=tony // reference to another bean
salesrep.department=Sales // real property
techie.(parent)=employee // derives from "employee" bean definition
techie.(scope)=prototype // bean is a prototype (not a shared instance)
techie.manager(ref)=jeff // reference to another bean
techie.department=Engineering // real property
techie.usesDialUp=true // real property (overriding parent value)
ceo.$0(ref)=secretary // inject 'secretary' bean as 0th constructor arg
ceo.$1=1000000 // inject value '1000000' at 1st constructor arg
我们在resource目录下创建一个beans.properties
car.(class)=com.example.lurenjia.spring.c22.jd1.d1.Car
car.name=name1
car1.(class)=com.example.lurenjia.spring.c22.jd1.d1.Car
car1.name=name2
public class Client {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(factory);
String location = "classpath:beans.properties";
int countBean = propertiesBeanDefinitionReader.loadBeanDefinitions(location);
System.out.println(String.format("共注册了 %s 个bean", countBean));
for (String beanName : factory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
String beanDefinitionClassName = beanDefinition.getClass().getName();
Object bean = factory.getBean(beanName);
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" + beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
}
}
注解方式:PropertiesBeanDefinitionReader
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Primary
@Lazy
public class Service1 {
}
public class Service2 {
@Autowired
private Service1 service1;
@Override
public String toString() {
return "Service2{" +
"service1=" + service1 +
'}';
}
}
public class Client {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);
annotatedBeanDefinitionReader.register(Service1.class, Service2.class);
for (String beanName : new String[]{"service1", "service2"}) {
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
String beanDefinitionClassName = beanDefinition.getClass().getName();
Object bean = factory.getBean(beanName);
System.out.println(beanName + ":");
System.out.println(" beanDefinitionClassName:" + beanDefinitionClassName);
System.out.println(" beanDefinition:" + beanDefinition);
System.out.println(" bean:" + bean);
}
}
}
这里为什么会输出一个null呢
在 for 循环上面添加一行代码
factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);
阶段3:Spring Bean注册阶段
一个重要的接口 BeanDefinitionRegistry
BeanDefinitionRegistry源码
public interface BeanDefinitionRegistry extends AliasRegistry {
//注册bean定义
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;
//移除bean定义
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//获取bean定义
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
//是否包含bean定义
boolean containsBeanDefinition(String beanName);
//获取bean定义名称
String[] getBeanDefinitionNames();
//获取bean定义数量
int getBeanDefinitionCount();
//beanName是否已经注册
boolean isBeanNameInUse(String beanName);
}
AliasRegistry
AliasRegistry 是 BeanDefinitionRegistry 的父接口
public interface AliasRegistry {
//注册别名
void registerAlias(String name, String alias);
//移除别名
void removeAlias(String alias);
//判断是不是别名
boolean isAlias(String name);
//获取别名数组
String[] getAliases(String name);
}
BeanDefinitionRegistry实现类
DefaultListableBeanFactory
public class Client {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
GenericBeanDefinition nameBdf = new GenericBeanDefinition();
nameBdf.setBeanClass(String.class);
nameBdf.getConstructorArgumentValues().addIndexedArgumentValue(0, "abcdefg");
factory.registerBeanDefinition("name", nameBdf);
System.out.println(factory.getBeanDefinition("name"));
System.out.println(factory.containsBeanDefinition("name"));
System.out.println(Arrays.asList(factory.getBeanDefinitionNames()));
System.out.println(factory.getBeanDefinitionCount());
System.out.println(factory.isBeanNameInUse("name"));
factory.registerAlias("name", "alias-name-1");
factory.registerAlias("name", "alias-name-2");
System.out.println(factory.isAlias("alias-name-1"));
System.out.println(Arrays.asList(factory.getAliases("name")));
System.out.println(factory.getBean("name"));
}
}
Generic bean: class [java.lang.String]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
true
[name]
1
true
true
[alias-name-2, alias-name-1]
10:25:45.492 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'name'
abcdefg
阶段4:BeanDefinition合并阶段
目的:
案例
public class LessonModel {
private String name;
private int lessonCount;
private String description;
//省略get set tostring
}
定义xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="lesson1" class="com.example.lurenjia.spring.c22.jd4.LessonModel"/>
<bean id="lesson2" parent="lesson1">
<property name="name" value="spring高手系列"/>
<property name="lessonCount" value="100"/>
</bean>
<bean id="lesson3" parent="lesson2">
<property name="description" value="路人甲Java带你学spring,超越90%开发者!"/>
</bean>
</beans>
public class Client {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(factory);
beanDefinitionReader.loadBeanDefinitions("classpath:c22jd4d1.xml");
for (String beanName : factory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
BeanDefinition mergedBeanDefinition = factory.getMergedBeanDefinition(beanName);
System.out.println(beanName);
System.out.println("解析xml过程中注册的beanDefinition:" + beanDefinition);
System.out.println("beanDefinition中的属性信息" + beanDefinition.getPropertyValues());
System.out.println("合并之后得到的mergedBeanDefinition:" + mergedBeanDefinition);
System.out.println("mergedBeanDefinition中的属性信息" + mergedBeanDefinition.getPropertyValues());
System.out.println("---------------------------");
}
}
}
lesson3
解析xml过程中注册的beanDefinition:Generic bean with parent 'lesson2':
class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0;
autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null;
initMethodName=null; destroyMethodName=null; defined in class path resource [c22jd4d1.xml]
beanDefinition中的属性信息PropertyValues: length=1; bean property 'description'
合并之后得到的mergedBeanDefinition:Root bean: class [com.example.lurenjia.spring.c22.jd4.LessonModel];
scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true;
primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null;
defined in class path resource [c22jd4d1.xml]
mergedBeanDefinition中的属性信息PropertyValues: length=3; bean property 'name'; bean property 'lessonCount';
bean property 'description'
阶段5:Bean Class加载阶段 (resolveBeanClass)
Resolve the bean class for the specified bean definition, resolving a bean class name into a Class reference (if necessary) and storing the resolved Class in the bean definition for further use.
将 bean definition 解析为 bean class.
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
throws CannotLoadBeanClassException {
try {
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
return doResolveBeanClass(mbd, typesToMatch);
}
}
catch (PrivilegedActionException pae) {
ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (ClassNotFoundException ex) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
}
catch (LinkageError err) {
throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
}
}
阶段6:Bean实例化阶段
createBean方法
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
resolveBeforeInstantiation
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
阶段7:合并后的BeanDefinition处理
doCreateBean类583行applyMergedBeanDefinitionPostProcessors
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
applyMergedBeanDefinitionPostProcessors
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
postProcessMergedBeanDefinition是MergedBeanDefinitionPostProcessor接口的方法
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
主要实现类 todo
阶段8:Bean属性设置阶段
// Initialize the bean instance. 初始化bean实例
Object exposedObject = bean;
try {
//填充bean,涉及阶段8
populateBean(beanName, mbd, instanceWrapper);
//初始化bean,涉及阶段9
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
populateBean方法源码
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//如果BeanWrapper为空
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
//当mbd.hasPropertyValues()返回false
else {
// Skip property population phase for null instance. 跳过这个阶段
return;
}
}
// 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) {
//如果postProcessAfterInstantiation返回false则跳过该阶段
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
//PropertyValues
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//阶段2
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 (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
阶段9:Bean初始化阶段(初始化)
包含阶段
这个阶段含有几个小阶段
-
Bean Aware接口回调
-
Bean初始化前
-
Bean初始化
-
Bean初始化后
主要原理 initializeBean 方法执行过程
AbstractAutowireCapableBeanFactory类609行
exposedObject = initializeBean(beanName, exposedObject, mbd);
AbstractAutowireCapableBeanFactory类initializeBean方法源码如下
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
//阶段1 处理aware方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
//阶段2 applyBeanPostProcessorsBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
//invokeInitMethods
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
//applyBeanPostProcessorsAfterInitialization
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Bean Aware接口回调
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-aware
Aware原理
initializeBean中关于invokeAwareMethods的调用
//阶段1 处理aware方法
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
aware翻译为:知道的;察觉的;了解的;关注的
public interface Aware {}
虽然Aware接口什么方法都没有,但是它有非常多的实现类,org.springframework.beans.factory这个包下以Aware结尾的接口。核心代码 AbstractAutowireCapableBeanFactory 类
private void invokeAwareMethods(String beanName, Object bean) {
//Aware
if (bean instanceof Aware) {
//BeanNameAware
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
//BeanClassLoaderAware
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//BeanFactoryAware
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
Aware案例
public class AwareBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {
@Override
public void setBeanName(String name) {
System.out.println("setBeanName:" + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory:" + beanFactory);
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("setBeanClassLoader:" + classLoader);
}
}
client
public class Client {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerBeanDefinition("awareBean",
BeanDefinitionBuilder.genericBeanDefinition(AwareBean.class).getBeanDefinition());
factory.getBean("awareBean");
}
}
输出
setBeanName:awareBean
setBeanClassLoader:sun.misc.Launcher$AppClassLoader@18b4aac2
setBeanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@30c7da1e: defining beans [awareBean]; root of factory hierarchy
Bean初始化 (postProcessBeforeInitialization)
原理
initializeBean中关于applyBeanPostProcessorsBeforeInitialization的调用
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
applyBeanPostProcessorsBeforeInitialization源码
@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;
}
根据源码processor.postProcessBeforeInitialization这一行就是这个方法的核心。
BeanPostProcessor接口中的postProcessBeforeInitialization默认实现
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
post 和 Process 通常翻译为:后处理,后续处理
Before 在。。之前
Initialization 初始化
所以这个方法的意思为在初始化之前进行的处理过程。
这个接口有2个实现类,比较重要:
ApplicationContextAwareProcessor 和 CommonAnnotationBeanPostProcessor
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)) {
return bean;
}
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareInterfaces(bean);
return null;
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
案例
Bean初始化(invokeInitMethods)
源码来自initializeBean第三部分,翻译为调用初始化方法
//invokeInitMethods
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
Give a bean a chance to react now all its properties are set, and a chance to know about its owning bean factory (this object). This means checking whether the bean implements InitializingBean or defines a custom init method, and invoking the necessary callback(s) if it does.
invokeInitMethods源码,翻译为调用初始化方法。
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
//bean是否实现InitializingBean接口
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
//如果是trace级别
if (logger.isTraceEnabled()) {
logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
//
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
((InitializingBean) bean).afterPropertiesSet();
return null;
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
//调用afterPropertiesSet
((InitializingBean) bean).afterPropertiesSet();
}
}
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
//调用 invokeCustomInitMethod
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
主要作用就是调用 afterPropertiesSet和invokeCustomInitMethod
afterPropertiesSet
public interface InitializingBean {
//在配置文件设置之后
void afterPropertiesSet() throws Exception;
}
invokeCustomInitMethod
protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
throws Throwable {
String initMethodName = mbd.getInitMethodName();
Assert.state(initMethodName != null, "No init method set");
Method initMethod = (mbd.isNonPublicAccessAllowed() ?
BeanUtils.findMethod(bean.getClass(), initMethodName) :
ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));
if (initMethod == null) {
if (mbd.isEnforceInitMethod()) {
throw new BeanDefinitionValidationException("Could not find an init method named '" +
initMethodName + "' on bean with name '" + beanName + "'");
}
else {
if (logger.isTraceEnabled()) {
logger.trace("No default init method named '" + initMethodName +
"' found on bean with name '" + beanName + "'");
}
// Ignore non-existent default lifecycle methods.
return;
}
}
if (logger.isTraceEnabled()) {
logger.trace("Invoking init method '" + initMethodName + "' on bean with name '" + beanName + "'");
}
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
ReflectionUtils.makeAccessible(methodToInvoke);
return null;
});
try {
AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
() -> methodToInvoke.invoke(bean), getAccessControlContext());
}
catch (PrivilegedActionException pae) {
InvocationTargetException ex = (InvocationTargetException) pae.getException();
throw ex.getTargetException();
}
}
else {
try {
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
}
catch (InvocationTargetException ex) {
throw ex.getTargetException();
}
}
}
Bean初始化后(postProcessAfterInitialization)
源码来自initializeBean第四部分
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
applyBeanPostProcessorsAfterInitialization方法分析
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
//当前bean
Object result = existingBean;
//循环使用BeanPostProcessor 来处理
for (BeanPostProcessor processor : getBeanPostProcessors()) {
//使用每个处理器的postProcessAfterInitialization方法处理
Object current = processor.postProcessAfterInitialization(result, beanName);
//如果处理后为null直接返回
if (current == null) {
return result;
}
result = current;
}
//所有的处理器处理完之后返回对象
return result;
}
BeanPostProcessor接口postProcessAfterInitialization方法的默认实现
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
阶段9总结
Bean初始化分为四个阶段,其中在初始化的前后分别有前后处理器处理。最前面是Aware接口的一些处理。
We recommend that you do not use the InitializingBean interface, because it unnecessarily couples the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a POJO initialization method.
我们不推荐使用InitializingBean,这样会导致Spring耦合。推荐@PostConstruct。
阶段10:所有单例bean初始化完成后阶段 (初始化后)
SmartInitializingSingleton
smart 轻量
initializing 初始化
singleton 单例
Callback interface triggered at the end of the singleton pre-instantiation phase during BeanFactory bootstrap.
at the end of the singleton pre-instantiation phase 在单例预实例化阶段之后,下面我们来一个案例
public class Entity implements SmartInitializingSingleton {
private static final Logger logger = LoggerFactory.getLogger(Entity.class);
public Entity() {
logger.info("entity is init ... ");
}
@Override
public void afterSingletonsInstantiated() {
logger.info("afterSingletonsInstantiated is callback");
}
}
输出
INFO com.example.lurenjia.spring.c22.jd11.Entity - entity is init ...
INFO com.example.lurenjia.spring.c22.jd11.Entity - afterSingletonsInstantiated is callback
通过实现SmartInitializingSingleton 在初始化后执行
DubboLoadBalancedRestTemplateAutoConfiguration 中的实践
@Override
public void afterSingletonsInstantiated() {
loadBalancerInterceptorBean = retryLoadBalancerInterceptor != null
? retryLoadBalancerInterceptor : loadBalancerInterceptor;
}
阶段11:Bean使用阶段
使用阶段相信大家都会不再赘述。
阶段12:Bean销毁阶段
案例1 DisposableBean
public class Entity13 implements DisposableBean {
private static final Logger logger = LoggerFactory.getLogger(Entity13.class);
public Entity13() {
logger.info("Entity13 is init ... ");
}
@Override
public void destroy() throws Exception {
logger.info("Entity13 is destroy ... ");
}
}
@Configuration
public class Config13 {
@Bean
Entity13 entity13() {
return new Entity13();
}
}
public class Client1 {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config13.class);
Entity13 bean = context.getBean(Entity13.class);
System.out.println(bean);
context.getBeanFactory().destroyBean(bean);
}
}
输出
com.example.lurenjia.spring.c22.jd13.Entity13 - Entity13 is init ...
com.example.lurenjia.spring.c22.jd13.Entity13@318ba8c8
com.example.lurenjia.spring.c22.jd13.Entity13 - Entity13 is destroy ...
案例2 @PreDestroy
public class Entity132 {
private static final Logger logger = LoggerFactory.getLogger(Entity13.class);
public Entity132() {
logger.info("Entity132 is init ... ");
}
@PreDestroy
public void destroy() {
logger.info("Entity132 is destroy ... ");
}
}
输出
INFO com.example.lurenjia.spring.c22.jd13.Entity13 - Entity132 is destroy ...
使用@PreDestroy标记销毁时调用的方法。
案例3 DestructionAwareBeanPostProcessor
public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {
private static final Logger logger = LoggerFactory.getLogger(MyDestructionAwareBeanPostProcessor.class);
@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
logger.info(beanName + "is destroy");
}
}
public class Client2 {
public static void main(String[] args) {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
//注册BeanPostProcessor
factory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
//向容器中注入3个单例bean
factory.registerBeanDefinition("entity2",
BeanDefinitionBuilder.genericBeanDefinition(Entity2.class)
.getBeanDefinition());
factory.preInstantiateSingletons();
factory.destroySingleton("entity2");
}
}
输出
INFO com.example.lurenjia.spring.c22.jd13.d2.Entity2 - Entity2 init ...
INFO com.example.lurenjia.spring.c22.jd13.d2.MyDestructionAwareBeanPostProcessor - entity2is destroy
总结
- 实现DisposableBean
- @PreDestroy标记销毁方法
- 针对BeanDefinition实现DestructionAwareBeanPostProcessor
We recommend that you do not use the DisposableBean callback interface, because it unnecessarily couples the code to Spring.
Spring官方建议不要使用DisposableBean接口,因为会和Spring进行耦合。
Alternatively, we suggest using the @PreDestroy annotation or specifying a generic method that is supported by bean definitions.
我们建议使用@PreDestroy或者指定bean定义支持的通用方法。
重要的类和接口
AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {}
BeanDefinitionRegistry
AutowiredAnnotationBeanPostProcessor
CommonAnnotationBeanPostProcessor
BeanDefinition