浅析Spring系列
Spring Bean的生命周期
Bean的创建过程非常复杂,考虑到分析主流程为目的,因此本文会重点关注单例Bean的生命周期,以及穿插在过程中的接口处理(如BeanPostProcessor接口)。Bean的生命周期整体上可以分为四个阶段:
- 实例化:Instantiation
- 设置属性:Populate
- 初始化:Initialization
- 销毁:Destruction
0. 概述
Bean的创建入口在AbstracrBeanFactory的抽象方法createBean上,具体到代码会在AbstractAutowireCapableBeanFactory的doCreateBean方法上
//AbstractAutowireCapableBeanFactory#doCreateBean
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// 实例化bean
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
// Bean属性赋值
populateBean(beanName, mbd, instanceWrapper);
// Bean初始化
exposedObject = initializeBean(beanName, exposedObject, mbd);
//注册销毁方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
1. 实例化 Instantiation
createBeanInstance方法内部有几种实例化方式:
- 通过Supplier接口
- 通过工厂方法(如:static方法创建)
- 通过构造器创建
- 通过无参构造器创建
//AbstractAutowireCapableBeanFactory#createBeanInstance
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
// Make sure bean class is actually resolved at this point.
Class<?> beanClass = resolveBeanClass(mbd, beanName);
// 1. Supplier创建
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// 2. 工厂方法创建
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// 3. 构造器创建
// Candidate constructors for autowiring?
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// Preferred constructors for default construction?
ctors = mbd.getPreferredConstructors();
if (ctors != null) {
return autowireConstructor(beanName, mbd, ctors, null);
}
// 4. 无参构造器创建
// No special handling: simply use no-arg constructor.
return instantiateBean(beanName, mbd);
}
在instantiateBean中会通过实例化策略进行实例化:实例化可以是基于反射,也可以是CGLIB。
//AbstractAutowireCapableBeanFactory#instantiateBean
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
Object beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
2. 设置属性 Populate
设置属性的内容比较多且复杂,此处关注主要流程即可。
2.1 依赖注入
此处主要考虑@Value、@Autoware这种方式的属性设置。
主要还是依赖BeanPostProcessor扩展来实现设置属性,子接口InstantiationAwareBeanPostProcessor会处理属性相关的内容,主要接口为postProcessProperties,而postProcessPropertyValues接口在Spring 5.1.x中被标记为废弃,就不重点分析。调用BeanPostProcessor逻辑如下:
//AbstractAutowireCapableBeanFactory#populateBean
for (BeanPostProcessor bp : getBeanPostProcessors()) java{
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逻辑如下
- ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor:当Bean实现了EnhancedConfiguration接口,会注入BeanFactory实例。没有属性相关的逻辑
- CommonAnnotationBeanPostProcessor:会处理@WebServiceRef、@EJB、@Resource这三个注解的注入。注入逻辑为构建InjectionMetadata(实际为WebServiceRefElement、EjbRefElement、ResourceElement三个不同的子类),然后调用inject方法。
- AutowiredAnnotationBeanPostProcessor:会处理@Autowired、@Autowired、@javax.inject.Inject这三个注解的注入。注入逻辑为构建InjectionMetadata(实际为子类AutowiredFieldElement针对属性;AutowiredMethodElement针对方法),然后调用inject方法。
以下内容主要分析AutowiredFieldElement的inject方法实现:主要两个操作
- 通过BeanFactory解析依赖获取依赖的值。依赖解析内部较为负责,此处不深入分析。
- 通过反射设置属性值。
//AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement#inject
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
//通过BeanFactory解析依赖
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
//通过反射设置属性
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
2.2 属性设置
在populateBean方法内,如果PropertyValues对象不为空的情况下,还会进行属性设置,调用applyPropertyValues方法。主要有三个逻辑:
- 解析属性值:会有一些特殊的类进行判断,如:NullBean则直接返回null值。如果是字段串的话,会通过Expression进行解析。
- 类型转换:最终会调用到TypeConverterDelegate的convertIfNecessary方法中。在没有自定义PropertyEditor的情况下,会先用ConversionService进行转换。关于PropertyEditor、ConversionService本文不重点阐述,此处知道有该逻辑即可。
- 设置属性值:内部逻辑比较复杂,此处知道有该逻辑即可。
//AbstractAutowireCapableBeanFactory#applyPropertyValues
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
//解析属性值
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
//类型转换
Object convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
//设置属性
bw.setPropertyValues(new MutablePropertyValues(deepCopy));
}
3. 初始化 Initialization
3.1 执行Aware方法
按先后顺序,会分别调用BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口
//AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);
}
//AbstractAutowireCapableBeanFactory#invokeAwareMethods
private void invokeAwareMethods(String beanName, 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);
}
}
}
3.2 调用BeanPostProcessor接口postProcessBeforeInitialization方法
此为Bean的扩展机制,可以通过该方法把Bean的实例给替换。而Spring内部更是通过此接口来扩展一些功能,内置的BeanPostProcessor及功能如下:
- ApplicationContextAwareProcessor:Aware接口调用,调用顺序如下:EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware
- ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor:调用ImportAware接口
- PostProcessorRegistrationDelegrate$BeanPostProcessorChecker:不处理
- CommonAnnotationBeanPostProcessor:调用@PostConstruct注解方法
- AutowiredAnnotationBeanPostProcessor:不处理
- ApplicationListenerDetector:不处理
//AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
}
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
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;
}
3.3 调用init方法
会先调用InitializingBean接口的afterPropertiesSet方法
//AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
((InitializingBean) bean).afterPropertiesSet();
}
}
然后再调用自定义初始化方法
//AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd){
if (mbd != null && bean.getClass() != NullBean.class) {
String initMethodName = mbd.getInitMethodName();
if (StringUtils.hasLength(initMethodName) &&
!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
!mbd.isExternallyManagedInitMethod(initMethodName)) {
invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
会先获取初始化方法Method,然后设置可访问,最后通过反射进行调用
//AbstractAutowireCapableBeanFactory#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 + "'");
}
return;
}
}
Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod);
ReflectionUtils.makeAccessible(methodToInvoke);
methodToInvoke.invoke(bean);
}
3.4 调用BeanPostProcessor接口postProcessAfterInitialization方法
此为Bean的扩展机制,可以通过该方法把Bean的实例给替换。Spring内部也通过此机制扩展一些功能
- ApplicationContextAwareProcessor:不处理
- ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor:不处理
- PostProcessorRegistrationDelegrate$BeanPostProcessorChecker:BeanPostProcessor检查,检测bean在所有BeanPostProcess实例化进行创建
- CommonAnnotationBeanPostProcessor:不处理
- AutowiredAnnotationBeanPostProcessor:不处理
- ApplicationListenerDetector:将实现ApplicationListener接口的bean,添加到ApplicationContext里。
//AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
}
//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
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;
}
4. 销毁 Destruction
4.1 注册销毁类
单例bean在创建的时候,会注册销毁类,便于在销毁的时候调用。销毁类用DisposableBeanAdapter适配,内部会调用真正的bean回调。
//AbstractBeanFactory#registerDisposableBeanIfNecessary
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
//注册销毁bean
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
触发单例bean执行销毁,在ConfigurableApplicationContext的close方法中。或者执行ShutdownHook(前提是有注册ShutdownHook),内部会调用destroyBeans,最终会在BeanFactory调用destroySingletons方法,内部又会调用destroyBean方法。
核心关注DisposableBean的destroy方法,根据前面注册,可以得知,它实际上就是DisposableBeanAdapter的destroy方法。
protected void destroyBean(String beanName, @Nullable DisposableBean bean) {
// Actually destroy the bean now...
if (bean != null) {
try {
bean.destroy();
}
catch (Throwable ex) {
if (logger.isWarnEnabled()) {
logger.warn("Destruction of bean with name '" + beanName + "' threw an exception", ex);
}
}
}
}
内部执行销毁方法分三部分,分别是:@PreDestory注解、DisposableBean接口和自定义销毁方法。
4.2 执行@PreDestory
@PreDestory注解是通过BeanPostProcessor处理,实际就是CommonAnnotationBeanPostProcessor。
//DisposableBeanAdapter#destroy
public void destroy() {
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
}
实际执行的方法是InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction,内部会通过封装的LifecycleMetadata类调用销毁方法。
//InitDestroyAnnotationBeanPostProcessor#postProcessBeforeDestruction
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
metadata.invokeDestroyMethods(bean, beanName);java
}
4.3 执行DisposableBean接口
内部直接转DisposableBean接口,调用其destroy方法
//DisposableBeanAdapter#destroy
public void destroy() {
((DisposableBean) this.bean).destroy();
}
4.4 执行自定义销毁方法
如果已经在构造器的时候获取了destroyMethod则直接调用;如果destroyMethodName 不为空,则尝试获取销毁的Method
//DisposableBeanAdapter#destroy
public void destroy() {
if (this.destroyMethod != null) {
invokeCustomDestroyMethod(this.destroyMethod);
}
else if (this.destroyMethodName != null) {
Method methodToInvoke = determineDestroyMethod(this.destroyMethodName);
if (methodToInvoke != null) {
invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(methodToInvoke));
}
}
}
在具体执行中,或先让该方法可以访问,然后通过反射,调用该自定义方法。
//DisposableBeanAdapter#invokeCustomDestroyMethod
private void invokeCustomDestroyMethod(final Method destroyMethod) {
ReflectionUtils.makeAccessible(destroyMethod);
destroyMethod.invoke(this.bean, args);
}
5. 参考链接
- Bean实例化:www.cnblogs.com/javastack/p…