当前位置:   article > 正文

Spring bean生命周期详解_spring bean的生命周期

spring bean的生命周期

Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。
在这里插入图片描述
在这里插入图片描述

Spring bean生命周期 四个阶段

Bean的实例化阶段
Bean的设置属性阶段
Bean的 初始化阶段
Bean的销毁阶段

Spring bean生命周期13个环节

阶段1:Bean元信息配置阶段
阶段2:Bean元信息解析阶段
阶段3:将Bean注册到容器中
阶段4:BeanDefinition合并阶段
阶段5:Bean Class加载阶段
阶段6:Bean实例化阶段(2个小阶段)
1.Bean实例化前阶段
2.Bean实例化阶段
阶段7:合并后的BeanDefinition处理
阶段8:属性赋值阶段(3个小阶段)
1.Bean实例化后阶段
2.Bean属性赋值前阶段
3.Bean属性赋值阶段
阶段9:Bean初始化阶段(5个小阶段)
1.Bean Aware接口回调阶段
2.Bean初始化前阶段
3.Bean初始化阶段
4.Bean初始化后阶段
5.Bean初始化完成
阶段10:所有单例bean初始化完成后阶段
阶段11:Bean的使用阶段
阶段12:Bean销毁前阶段
阶段13:Bean销毁阶段

阶段1:Bean元信息配置阶段

这个阶段主要是bean信息的定义阶段
Bean信息定义4种方式

  1. API的方式
  2. Xml文件方式
  3. 注解的方式
    类上标注@Compontent注解来定义一个bean
    配置类中使用@Bean注解来定义bean
  4. properties文件的方式
    Spring容器启动的过程中,会将Bean解析成Spring内部的BeanDefinition结构。

不管是是通过xml配置文件的标签,还是通过注解配置的@Bean,还是@Compontent标注的类,还是扫描得到的类,它最终都会被解析成一个BeanDefinition对象,最后我们的Bean工厂就会根据这份Bean的定义信息,对bean进行实例化、初始化等等操作。

你可以把BeanDefinition丢给Bean工厂或者其子类,然后Bean工厂就会根据这个信息帮你生产一个Bean实例
一般用的是beanFactory的子类applicationcontext, applicationcontext比一般的beanFactory要多很多功能,比如aop、事件等。
通过t加载配置文件,或者利用注解的方式扫描将bean的配置信息加载到spring容器里面。

在这里插入图片描述

BeanDefinition接口:bean定义信息接口
AttributeAccessor接口:属性访问接口
BeanMetadataElement接口:返回BeanDefinition定义的来源
RootBeanDefinition类:表示根bean定义信息
ChildBeanDefinition类:表示子bean定义信息
GenericBeanDefinition类:通用的bean定义信息
ConfigurationClassBeanDefinition类:表示通过配置类中@Bean方法定义bean信息
AnnotatedBeanDefinition接口:表示通过注解的方式定义的bean信息
BeanDefinitionBuilder:构建BeanDefinition的工具类,可以非常方便的组装BeanDefinition对象

@Component 和 @Bean 的区别

Spring帮助我们管理Bean分为两个部分,一个是注册Bean,一个装配Bean。
完成这两个动作有三种方式,一种是使用自动配置的方式、一种是使用JavaConfig的方式,一种就是使用XML配置的方式。

@Compent 作用就相当于 XML配置

@Component
public class Student {

    private String name = "lkm";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

@Bean 需要在配置类中使用,即类上需要加上@Configuration注解

@Configuration
public class WebSocketConfig {
    @Bean
    public Student student(){
        return new Student();
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

两者都可以通过@Autowired装配

@Autowired Student student;

那为什么有了@Compent,还需要@Bean呢?
如果你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component注解的,因此就不能使用自动化装配的方案了,但是我们可以使用@Bean,当然也可以使用XML配置。

阶段2:Bean元信息解析阶段

Bean元信息的解析主要有3种方式

  1. xml文件定义bean的解析
    XML方式解析:XmlBeanDefinitionReader
  2. properties文件定义bean的解析
    properties文件定义bean的解析:PropertiesBeanDefinitionReader
  3. 注解方式定义bean的解析
    AnnotatedBeanDefinitionReader
    BeanDefinationReader的作用就是加载配置元信息,并将其转化为内存形式的BeanDefination

阶段3:Spring Bean注册阶段

bean注册阶段需要用到一个非常重要的接口:BeanDefinitionRegistry

别名注册接口:AliasRegistry
BeanDefinitionRegistry接口继承了AliasRegistry接口,这个接口中定义了操作bean别名的一些方法。

BeanDefinitionRegistry唯一实现:DefaultListableBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory
例如 AnnotationConfigApplicationContext 类就实现了 BeanDefinitionRegistry接口

Spring通过BeanDefinationReader将配置元信息加载到内存生成相应的BeanDefination之后,就将其注册到BeanDefinationRegistry中,BeanDefinationRegistry就是一个存放BeanDefination的大篮子,它也是一种键值对的形式,通过特定的Bean定义的id,映射到相应的BeanDefination。

getBean这个方法的源码
org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

阶段4:BeanDefinition合并阶段

org.springframework.beans.factory.support.AbstractBeanFactory#getMergedBeanDefinition
bean定义可能存在多级父子关系,合并的时候进进行递归合并,最终得到一个包含完整信息的RootBeanDefinition.

合并之前是GenericBeanDefinition类型的,合并之后得到的是RootBeanDefinition类型的。

后面的阶段将使用合并产生的RootBeanDefinition

阶段5:Bean Class加载阶段

这个阶段就是将bean的class名称转换为Class类型的对象。

此时会对阶段4中合并产生的RootBeanDefinition中的beanClass进行解析,将bean的类名转换为Class对象,然后赋值给RootBeanDefinition#setBeanClassName字段

上面得到了Bean Class对象以及合并之后的BeanDefinition,下面就开始进入实例化这个对象的阶段了。
Bean实例化分为3个阶段:前阶段、实例化阶段、后阶段;

阶段6:Bean实例化阶段

Bean实例化前操作

看一下 DefaultListableBeanFactory

在 父类 AbstractBeanFactory 中
private final List beanPostProcessors = new CopyOnWriteArrayList<>();
是一个BeanPostProcessor类型的集合

spring在bean生命周期的不同阶段,会调用上面这个列表中的BeanPostProcessor中的一些方法,来对生命周期进行扩展,bean生命周期中的所有扩展点都是依靠这个集合中的BeanPostProcessor来实现的

Bean实例化之前会调用一段代码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation

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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

上面代码中轮询beanPostProcessors列表,如果类型是InstantiationAwareBeanPostProcessor, 尝试调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation获取bean的实例对象,如果能够获取到,那么将返回值作为当前bean的实例,那么spring自带的实例化bean的过程就被跳过了.

这个地方给开发者提供了一个扩展点,允许开发者在这个方法中直接返回bean的一个实例

Bean实例化操作
这个过程可以干什么?

这个过程会通过反射来调用bean的构造器来创建bean的实例。
org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
这个方法会返回候选的构造器列表,也可以返回空.

protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(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;
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

具体需要使用哪个构造器,spring为开发者提供了一个接口,允许开发者自己来判断用哪个构造器。
重要的实现类 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
可以将@Autowired标注的方法作为候选构造器返回
到目前为止bean实例化阶段结束了

阶段7:合并后的BeanDefinition处理

这块的源码如下
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors

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);
		}
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

会调用MergedBeanDefinitionPostProcessor接口的postProcessMergedBeanDefinition方法

第一个参数为beanDefinition,表示合并之后的RootBeanDefinition,我们可以在这个方法内部对合并之后的BeanDefinition进行再次处理

实现类
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Autowired、@Value 标注的方法、字段进行缓存

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
在 postProcessMergedBeanDefinition 方法中对 @Resource 标注的字段、@Resource 标注的方法、 @PostConstruct 标注的字段、 @PreDestroy标注的方法进行缓存

阶段8:Bean属性设置阶段

(1)调用 InstantiationAwareBeanPostProcessor 处理器的 postProcessAfterInstantiation 方法,判断控制程序是否继续进行属性填充

(2)根据注入类型(byType/byName),提取依赖的,统一存入 PropertyValues 中

(3)判断是否需要进行 BeanPostProcessor 和 依赖检查:

如果有后置处理器,将会应用 InstantiationAwareBeanPostProcessor 处理器的postProcessProperties 方法,对属性获取完毕填充前,对属性进行再次处理。 使用 checkDependencies方法来进行依赖检查
(4)将所有解析到的 PropertyValues 中的属性填充至 BeanWrapper 中

实例化后阶段
会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation这个方法,调用逻辑如下:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

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

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

postProcessAfterInstantiation方法返回false的时候,后续的Bean属性赋值前处理、Bean属性赋值都会被跳过

Bean属性赋值前阶段
这个阶段会调用InstantiationAwareBeanPostProcessor接口的postProcessPropertyValues方法,调用逻辑
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

if (hasInstAwareBpps || needsDepCheck) {
	PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
	if (hasInstAwareBpps) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
				if (pvs == null) {
					return;
				}
			}
		}
	}
	if (needsDepCheck) {
		checkDependencies(beanName, mbd, filteredPds, pvs);
	}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

如果InstantiationAwareBeanPostProcessor中的postProcessPropertyValues返回空的时候,表示这个bean不需要设置属性,直接返回了,直接进入下一个阶段
PropertyValues 保存了bean实例对象中所有属性值的设置,所以我们可以在postProcessPropertyValues 这个方法中对PropertyValues值进行修改。

这个方法有2个比较重要的实现类

AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues在这个方法中对@Autowired、@Value标注的字段、方法注入值。
CommonAnnotationBeanPostProcessor#postProcessPropertyValues在这个方法中对@Resource标注的字段和方法注入值。
Bean属性赋值阶段
这个过程比较简单了,循环处理PropertyValues中的属性值信息,通过反射调用set方法将属性的值设置到bean实例中。

PropertyValues中的值是通过bean xml中property元素配置的,或者调用MutablePropertyValues中add方法设置的值。

阶段9:Bean初始化阶段

这个阶段分为5个小的阶段

Bean Aware接口回调
Bean初始化前操作
Bean初始化操作
Bean初始化后操作
Bean初始化完成操作
Bean Aware接口回调

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

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) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

BeanNameAware:将bean的名称注入进去
BeanClassLoaderAware:将BeanClassLoader注入进去
BeanFactoryAware:将BeanFactory注入进去

Bean初始化前操作
这个阶段的源码
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

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

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessBeforeInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

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

通常称postProcessBeforeInitialization这个方法为:bean初始化前操作。

这个接口有2个实现类,比较重要:
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调用@PostConstruct标注的方法
CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization中会调用bean中所有标注@PostConstruct注解的方法

ReflectionUtils.doWithLocalMethods(targetClass, new ReflectionUtils.MethodCallback() {
	@Override
	public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
		if (initAnnotationType != null) {
			if (method.getAnnotation(initAnnotationType) != null) {
				LifecycleElement element = new LifecycleElement(method);
				currInitMethods.add(element);
				if (debug) {
					logger.debug("Found init method on class [" + clazz.getName() + "]: " + method);
				}
			}
		}
		if (destroyAnnotationType != null) {
			if (method.getAnnotation(destroyAnnotationType) != null) {
				currDestroyMethods.add(new LifecycleElement(method));
				if (debug) {
					logger.debug("Found destroy method on class [" + clazz.getName() + "]: " + method);
				}
			}
		}
	}
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

调用@PostConstruct标注的方法

Bean初始化阶段
2个步骤
调用InitializingBean接口的afterPropertiesSet方法
调用定义bean的时候指定的初始化方法。
见:com.dn.spring.beandefinition.BeanDefinition5Test#test7

Bean初始化后阶段
这块的源码:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

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

	Object result = existingBean;
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

调用BeanPostProcessor接口的postProcessAfterInitialization方法,返回null的时候,会中断上面的操作。
通常称 postProcessAfterInitialization 这个方法为:bean初始化后置操作。

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

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

public interface SmartInitializingSingleton {
    void afterSingletonsInstantiated();
}
  • 1
  • 2
  • 3

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

这个方法内部会先触发所有非延迟加载的单例bean初始化,然后从容器中找到类型是SmartInitializingSingleton的bean,调用他们的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接口

public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {

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

    /**
     * 用来判断bean是否需要触发postProcessBeforeDestruction方法
     */
    default boolean requiresDestruction(Object bean) {
        return true;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

总结:

BeanDefination(bean定义配置-解析-注册):

配置元信息(bean定义配置)-BeanDefinationReader(解析)-BeanDefinationRegistry(注册);
配置元信息(bean定义配置):API的方式,Xml文件方式,注解的方式,properties文件
BeanDefinationRegistry:;键值对方式,通过特定的Bean定义的id,映射到相应的BeanDefination

Bean实例化阶段:Bean实例化分为3个阶段:前阶段(容器启动,Bean Class加载BeanDefination)、实例化阶段、后阶段;

BeanFactoryPostProcessor:是容器启动阶段Spring提供的一个扩展点,主要对注册的BeanDefination进行一定程度上的修改与替换。
例如类名、scope、属性、构造函数参数列表、依赖的bean、是否是单例类、是否是懒加载等,
容器的启动阶段的最终产物就是注册到BeanDefinationRegistry中的一个个BeanDefination了,这就是Spring为Bean实例化所做的预热的工作。

spring bean实例化之后,就开始注入属性,
首先注入自定义的属性,比如标注@autowrite的这些属性,
再调用各种Aware接口扩展方法,注入属性(spring特有的属性),
比如BeanNameAware.setBeanName,设置Bean的ID或者Name;

在这里插入图片描述

a.实例化Bean
容器通过获取BeanDefinition对象中的信息进行实例化。并且这一步仅仅是简单的实例化,并未进行依赖注入。

对于BeanFactory容器,当客户向容器请求一个尚未初始化的bean时,或初始化bean的时候需要注入另一个尚未初始化的依赖时,容器就会调用createBean进行实例化。
对于ApplicationContext容器,当容器启动结束后,便实例化所有的bean。

实例化对象被包装在BeanWrapper对象中(可以认为是Bean的原生态),BeanWrapper提供了设置对象属性的接口,避免了使用反射机制设置属性。

这里提到了4个组件:BeanFacotry\ApplicationContext\BeanDefinition\BeanWrapper

b.设置对象属性(依赖注入)
实例化后的对象被封装在BeanWrapper对象中,并且此时对象仍然是一个原生的状态,并没有进行依赖注入。
紧接着,Spring根据BeanDefinition中的信息进行依赖注入。
并且通过BeanWrapper提供的设置属性的接口完成依赖注入。

c.注入Aware接口(给bean增加某种能力,申明是某种特殊的bean)
Aware接口用于增强Bean能力容器需检测该对象是否实现了xxxAware接口,并将相关的xxxAware实例注入给bean。
常见的Aware接口有:BeanNameAware\BeanFactoryAware\ApplicationContextAware至此,一个对象已经被正确构造。

d.1.BeanPostProcessor(自定义处理,满足用户需求)
经过上述几个步骤后,bean对象已经被正确构造,但如果你想要对象被使用前再进行一些自定义的处理,就可以通过BeanPostProcessor接口实现。 该接口提供了两个函数:

postProcessBeforeInitialzation( Object bean, String beanName )
当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会先于InitialzationBean执行,因此称为前置处理。所有Aware接口的注入就是在这一步完成的。

postProcessAfterInitialzation( Object bean, String beanName )
当前正在初始化的bean对象会被传递进来,我们就可以对这个bean作任何处理。 这个函数会在InitialzationBean完成后执行,因此称为后置处理。
组件:BeanPostProcessor

d.2.InitializingBean与init-method
当BeanPostProcessor的前置处理完成后就会进入本阶段。 InitializingBean接口只有一个函数:afterPropertiesSet()这一阶段也可以在bean正式构造完成前增加我们自定义的逻辑,但它与前置处理不同,由于该函数并不会把当前bean对象传进来,因此在这一步没办法处理对象本身,只能增加一些额外的逻辑。
若要使用它,我们需要让bean实现该接口,并把要增加的逻辑写在该函数中。然后Spring会在前置处理完成后检测当前bean是否实现了该接口,并执行afterPropertiesSet函数。
当然,Spring为了降低对客户代码的侵入性,给bean的配置提供了init-method属性,该属性指定了在这一阶段需要执行的函数名。Spring便会在初始化阶段执行我们设置的函数。init-method本质上仍然使用了InitializingBean接口。

e.DisposableBean和destroy-method
和init-method一样,通过给destroy-method指定函数,就可以在bean销毁前执行指定的逻辑。

关于Aware

在设置属性阶段后,postProcessBeforeInitialization方法执行前,会执行很多Aware类型的接口,这种类型接口作用是加载资源到Spring容器中,Aware前面的名字就对应哪种资源,依次加载的是:

BeanNameAware
BeanClassLoaderAware
BeanFactoryAware
EnvironmentAware
ResourceLoaderAware
ApplicationEventPublisherAware
ApplicationContextAware
看到这里应该明白BeanFactory和ApplicationContext的区别了:
BeanFactoryAware之前加载的资源都是公共的。BeanFactoryAware后面加载的资源都是ApplicationContext独有的。

容器级扩展点(作用于所有bean):

BeanFactoryPostProcessor接口:
在循环初始化springbean之前,对BeanDefinition元数据做扩展处理
InstantiationAwareBeanPostProcessor接口: 在对象实例化前后扩展,作用于所有bean
BeanPostProcessor接口: 在对象初始化化前后扩展,作用于所有bean

(2)、Bean扩展点(作用于单个bean):

Aware接口: springBean实例化并且注入自定义属性之后 InitializingBean接口:
springBean初始化时,执行构造方法结束,并且属性赋初始化值结束之后执行 DiposableBean接口:
springBean销毁之前执行。

(3)、Bean自身的方法

包括了Bean本身调用的方法
通过配置文件中的init-method和destroy-method指定的方法(或者用注解的方式)
(4)、包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor,
CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。
工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/花生_TL007/article/detail/66359
推荐阅读
相关标签
  

闽ICP备14008679号