Spring 是一个 IOC 容器框架,拥有 DI 依赖注入(Dependency Injection),DL 依赖查找(Dependency Lookup)等功能。下面是根据源码分析出四个阶段,做出的生命周期解读:
- 注册阶段
- 实例化阶段
- 初始化阶段
- 销毁阶段
从图中可以看到,Bean 的完整生命周期从 Spring 容器着手实例化 Bean 开始,直到最终销毁 Bean。其中经历了许多关键点,可以将这些方法大致划分为 3 类:
Bean 自身的方法:如调用构造函数实例化、调用 Setter 设置属性值以及 init-method、destroy-method 指定的方法。
Bean 级生命周期接口方法:如 Aware 接口的属性赋值、InitializingBean、DisposableBean 接口
容器级生命周期接口方法,主要由 InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 两个接口实现,一般称它们的实现类为后处理器。后处理器以容器附加装置的形式注册到 Spring 容器中,当 Spring 容器创建任何 Bean 时,这些后处理器都会发生作用,所以这些后处理器的影响是全局性的。
注册阶段
注册阶段主要任务是通过各种 BeanDefinitionReader 读取扫描各种配置来源信息(XML 文件、注解等),并转换为 BeanDefinition 的过程。然后,最终会将扫描到的类整体注册到一个 DefaultListableBeanFactory 的 Map 容器中,便于之后获取使用。
1. BeanDefinition
BeanDefinition 可以理解为类的定义,描述一个类的基本情况。它完整的描述了在 Spring 的配置文件中定义的
2. BeanDefinitionReader
Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件或注解信息的解析。这个解析过程主要通过下图中的类完成:
3. SpringBoot 注册
在 Spring Boot 中,注册 Bean 的入口就是 run 方法中的 prepareContext 方法:
public ConfigurableApplicationContext run(String... args) {
......
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
......
}
在 prepareContext 方法中,会创建一个 BeanDefinitionLoader 对象,并执行它的 load 方法:
protected void load(ApplicationContext context, Object[] sources) {
BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
if (this.beanNameGenerator != null) {
loader.setBeanNameGenerator(this.beanNameGenerator);
}
if (this.resourceLoader != null) {
loader.setResourceLoader(this.resourceLoader);
}
if (this.environment != null) {
loader.setEnvironment(this.environment);
}
loader.load();
}
在 BeanDefinitionLoader 的 load 方法中,会通过 AnnotatedBeanDefinitionReader 来读取 Spring Boot 启动类上的注解信息,进而注册 Bean。
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
// 生成BeanDefinition信息
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
// 判断是否有@Conditional注解,以及是否满足bean注册条件
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
// 解析@Scope注解,确定Bean作用范围
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 生成Bean名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// 处理Bean相关的通用注解,如@Lazy、@Primary、@DependsOn等
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
...
// 允许对BeanDefinition进行一些自定义修改
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 默认作用域为单例且不进行代理
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 向容器中注册Bean定义信息
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
在 registerBeanDefinition 方法中,最终会注册到 DefaultListableBeanFactory 容器中:
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
// 存储注册信息的BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// beanDefinitionMap的数据结构是ConcurrentHashMap,因此不能保证顺序,为了记录注册的顺序,这里使用了ArrayList类型beanDefinitionNames用来记录注册顺序
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException {
......
// 注册过程
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
}
}
4. 相关注解配置
Spring 提供了 @Component、@Repository、@Service、@Controller 注解,因此我们可以使用特定的注解标注特定的 Bean。标注好 Bean 后,可以通过 @ComponentScan 注解扫描指定类路径来加载 Bean。
Bean 加载过程:
Spring 可以通过 @Autowired 进行自动注入,该注解可以作用在变量、setter 方法、构造函数上,默认通过类型匹配的方式在容器中查找匹配的 Bean,如果容器中没有类型匹配的 Bean,那么 Spring 容器启动时将抛出 NoSuchBeanDefinitionException 异常。可以将其 required 属性设置为 false 避免在匹配不到 Bean 时抛出异常。如果容器中有一个以上匹配的 Bean 时,则可以通过 @Qualifier 注解限定 Bean 的名称(byName)。
如果对集合类的变量进行 @Autowired 标注,那么 Spring 会将容器中匹配集合元素类型的所有 Bean 都自动注入进来。默认情况下,Bean 注入的顺序是不确定的,我们可以通过 @Order 注解或实现 Ordered 接口来决定 Bean 加载的顺序,值越小越优先被加载。
此外,Spring 还支持延迟依赖注入,即在 Spring 容器启动时,对于在 Bean 上标注 @Lazy 及 @Autowired 注解的属性,不会立即注入属性值,而是延迟到调用此属性的时候才会注入属性值。对 Bean 实施依赖注入时,@Lazy 注解必须同时标注在属性及目标 Bean 上。
@Lazy
@Component
public class AppQuotaOne {
}
@Component
public class AppQuotaSpringTest {
@Lazy
@Autowired
private AppQuota appQuotas;
}
Spring 也支持 @Resource 标准注解,@Resource 注解要求提供一个 Bean 名称的属性(byName),如果属性为空,则自动采用标注处的变量名或方法名作为 Bean 的名称。
Bean 作用范围及生命过程方法:
通过注解配置的 Bean 和通过
| singleton | 在 Spring IoC 容器中仅存在一个 Bean 实例,Bean 以单例方式存在。
默认 ApplicationContext 容器在启动时会自动实例化所有 singleton 的 Bean 并缓存于容器中,这样当运行时就无须实例化了。如果用户不希望提前实例化,可以通过 lazy-init 属性进行控制 | | —- | —- | | prototype | 每次从容器中调用 Bean 时,都返回一个新的实例,即每次调用 getBean() 时,相当于执行 new XXXBean() 操作。Spring 容器启动时不会实例化 prototype 的 Bean | | request | 每次 HTTP 请求都会创建一个新的 Bean,该作用域仅适用于 WebApplicationContext | | session | 同一个 HTTP Session 共享一个 Bean,不同的 HTTP Session 使用不同的 Bean,该作用域仅适用于 WebApplicationContext | | globalSession | 同一个全局 Session 共享一个 Bean,该作用域仅适用于 WebApplicationContext |
在使用
使用 Java 类提供 Bean 定义信息:
普通的 POJO 只要标注 @Configuration 注解,就可以为 Spring 容器提供 Bean 定义信息,每个标注了 @Bean 的类方法都相当于提供了一个 Bean 的定义信息。Bean 的类型由方法返回值的类型决定,名称默认和方法名相同(也可通过 name 属性显示指定名称)。@Bean 所标注的方法体提供了 Bean 的实例化逻辑。
Spring 提供了一个 AnnotationConfigApplicationContext 类,它能够直接通过标注 @Configuration 的 Java 类启动 Spring 容器。此外,还支持手动加载多个配置类,然后通过刷新容器应用这些配置类。Spring 也提供了一个 @Import 注解将多个配置类组装到一个配置类中,这样仅需要注册这个组装好的配置类即可启动容器。
实例化阶段
当 IOC 容器启动并装载 Bean 之后,并不会直接初始化 Bean,而是等到第一次调用的时候才会去初始化。在实例化阶段,Spring 主要将 BeanDefinition 转换为实例 Bean,并放在包装类 BeanWrapper 中。无论是否设置 Bean 的懒加载方式,最后都会通过 AbstractBeanFactory.getBean() 方法进行实例化:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
// 获取beanName
final String beanName = transformedBeanName(name);
Object bean;
// 检查缓存中或者singletonFactories中的ObjectFactory中是否有对应的实例
// 因为在创建单例bean的时候会存在依赖注入的情况,而在创建依赖时为了避免循环依赖,
// Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光
// 也就是将ObjectFactory加入到缓存中,一旦下个 bean 创建时要依赖上个 bean 则直接使用ObjectFactory
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
...
// 返回对应的实例,有时存在诸如FactoryBean的情况并不是直接返回实例本身而是返回指定方法返回的实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 只有在单例情况下才会尝试解决循环依赖
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
BeanFactory parentBeanFactory = getParentBeanFactory();
// 如果在当前所有已加载的类中不包含beanName,则尝试从parentBeanFactory中检测
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
} else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else if (requiredType != null) {
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
String[] dependsOn = mbd.getDependsOn();
// 若存在依赖则需要递归实例化依赖的bean
if (dependsOn != null) {
for (String dep : dependsOn) {
// 缓存依赖调用关系
registerDependentBean(dep, beanName);
getBean(dep);
}
}
// 实例化依赖的 bean 后便可以实例化自身了
// 单例模式创建bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建bean实例
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 原型模式创建bean
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
// 指定的scope上实例化bean
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
}
}
}
// 检查需要的类型是否符合实际的类型
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
}
return (T) bean;
}
1. FactoryBean
一般情况下,Spring 通过反射机制利用 bean 的 class 属性指定实现类来实例化 bean。但在某些情况下,实例化 bean 过程比较复杂,如果按照传统的方式,则需要在
public interface FactoryBean<T> {
// 返回由FactoryBean创建的Bean实例,如果isSingleton()返回true,则该实例还会放到Spring容器的单实例缓存池中
T getObject() throws Exception;
// 返回由FactoryBean创建的Bean的类型
Class<?> getObjectType();
// 确定由FactoryBean创建的Bean的作用域是singleton还是prototype
default boolean isSingleton() { return true; }
}
当
2. getObjectForBeanInstance
在 getBean 方法中,getObjectForBeanlnstance 是个高频率使用的方法,无论是从缓存中获得 bean 还是根据不同的 scope 策略加载 bean。总之,我们得到 bean 的实例后要做的第一步就是调用这个方法来检测一下正确性,其实就是用于检测当前 bean 是否是 FactoryBean 类型的 bean,如果是,那么需要调用该 bean 对应的 FactoryBean 实例中的 getObject() 作为返回值。
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// name是否以&为前缀
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 如果指定的name是工厂相关(以&为前缀)且beanInstance又不是FactoryBean类型则验证不通过
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
if (mbd != null) {
mbd.isFactoryBean = true;
}
// 返回FactoryBean自身
return beanInstance;
}
// 普通bean直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 加载FactoryBean
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
} else {
// 尝试从缓存中加载bean
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 调用FactoryBean的getObject方法返回自定义的bean实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
3. getSingleton
在 Spring 加载 Bean 的过程中使用了 getSingleton 方法实现单例 Bean 的加载过程:
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
// 全局变量需要同步
synchronized (this.singletonObjects) {
// 首先检查对应的bean是否已经加载过,因为singleton模式其实就是复用已创建的bean,所以这一步是必须的
Object singletonObject = this.singletonObjects.get(beanName);
// 如果为空才可以进行singleton的bean的初始化
if (singletonObject == null) {
// 单例创建之前的回调
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet<>();
}
try {
// 初始化bean
singletonObject = singletonFactory.getObject();
newSingleton = true;
} finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 单例创建后的回调
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 加入缓存
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
}
上述代码中其实是使用了回调方法,使得程序可以在单例创建的前后做一些准备及处理操作,而真正的获取单例 bean 的方法其实并不是在此方法中实现的,其实现逻辑是在 ObjectFactory 类型的实例 singletonFactory 中实现的。
4. createBean
ObjectFactory 中真正创建 Bean 的动作是由外部传入的一个函数来实际执行的,即 AbstractFactoryBean 中的 creatBean 方法。在 createBean 的方法实现中,其子类 AbstractAutowireCapableBeanFactory 又重写了该方法,具体如下:
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
RootBeanDefinition mbdToUse = mbd;
// 根据设置的 class 属性或者根据 className 来解析 Class
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// 验证及准备覆盖的方法
mbdToUse.prepareMethodOverrides();
try {
// 给BeanPostProcessors一个机会来返回代理来替代真正的对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
try {
// 真正创建bean的动作
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance;
}
}
在真正调用 doCreateBean 方法创建 bean 的实例前调用了 resolveBeforeInstantiation 方法对 BeanDefiniton 中的属性做些前置处理。
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
// 如果尚未被解析
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
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;
}
- 实例化前的后处理器应用:applyBeanPostProcessorsBeforeInstantiation
- 实例化后的后处理器应用:applyBeanPostProcessorsAfterInitialization
5. doCreateBean
当经历过 resolveBeforeInstantiation 方法后,程序有两个选择,如果创建了代理或者说重写了 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法并在方法中改变了 bean,则直接返回就可以了,否则需要进行常规 bean 的创建。而常规 bean 的创建就是在 doCreateBean 中完成的。
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 根据指定bean使用对应的策略创建新的实例,如:工厂方法、构造函数自动注入、简单初始化
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// 应用MergedBeanDefinitionPostProcessor后处理器
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
mbd.postProcessed = true;
}
}
// 是否需要提早曝光:单例、允许循环依赖、当前bean正在创建中,检测循环依赖
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 为避免后期循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory 加入工厂
// getEarlyBeanReference中主要应用SmartInstantiationAwareBeanPostProcessor处理器,AOP的动态织入就是在这里完成的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
// 对bean进行填充,将各个属性值注入,其中可能存在依赖于其他bean的属性,则会递归初始依赖bean
populateBean(beanName, mbd, instanceWrapper);
// 激活Aware接口,注入相应的实例
// 调用BeanPostProcessor的postProcessBeforeInitialization
// 调用bean的初始化方法,比如InitializingBean接口的afterPropertiesSet方法
// 调用BeanPostProcessor的postProcessAfterInitialization
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
// earlySingletonReference只有在检测到有循环依赖的情况下才会不为空
if (earlySingletonReference != null) {
// 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
} else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
// 检测依赖
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
// 因为bean创建后其所依赖的bean一定是已创建的
// actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部创建完,也就是说存在循环依赖
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(...);
}
}
}
}
// 注册DisposableBean,如果配置了destroy-method,这里需要注册以便于在销毁时候调用
registerDisposableBeanIfNecessary(beanName, bean, mbd);
return exposedObject;
}
BeanWrapper 相当于一个代理器,Spring 委托 BeanWrapper 完成 Bean 属性的填充工作。这是通过调用 setWrappedInstance(Object obj) 方法完成的。
BeanWrapper 还有两个顶级类接口:PropertyAccessor 和 PropertyEditorRegistry。前者定义了各种访问 Bean 属性的方法,而后者是属性编辑器的注册表。Spring 从 BeanDefinition 中获取 Bean 属性的配置信息 PropertyValue,并使用属性编辑器对 PropertyValue 进行转换以得到 Bean 的属性值。
初始化阶段
初始化阶段主要是在返回 Bean 实例之前做一些处理,主要由 AbstractAutowireCapableBeanFactory 提供的 initializeBean() 方法来实现。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
// JDK的安全机制验证权限
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
} else {
// 为Bean注入相应的Aware接口表示的实例
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
// 对BeanPostProcessor后置处理器的postProcessBeforeInitialization回调方法的调用,为Bean实例初始化前做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 调用Bean实例对象初始化的方法,这个初始化方法是在Spring Bean定义配置文件中通过init-method属性指定的
// 或者实现了InitializingBean接口的afterPropertiesSet方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
// 对BeanPostProcessor后置处理器的postProcessAfterInitialization回调方法的调用,为Bean实例初始化之后做一些处理
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
Spring Aware 的目的是为了让 Bean 获得 Spring 容器的服务,常用的 Aware 接口如下:
BeanNameAware | 获取到容器中 Bean 的名称 |
---|---|
BeanFactoryAware | 获取当前 BeanFactory,这样可以调用容器的服务 |
ApplicationContextAware | 获取当前 ApplicationContext,这样可以调用容器的服务 |
ApplicationEventPublisherAware | 获取 ApplicationEventPublisher,可以发布事件 |
ResourceLoaderAware | 获得资源加载器,可以获得外部资源文件 |
销毁阶段
一般是在 ApplicationContext 关闭的时候调用,也就是 AbstractApplicationContext.close() 方法。在注册的时候 Spring 通过适配器模式包装了一个类 DisposableBeanAdapter,在销毁阶段的时候会获得这个类,进而调用到 DisposableBeanAdapter.destroy() 方法:
public void destroy() {
// @PreDestroy注解的支持
if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
processor.postProcessBeforeDestruction(this.bean, this.beanName);
}
}
// DisposableBean接口的支持
if (this.invokeDisposableBean) {
((DisposableBean) this.bean).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));
}
}
}
销毁阶段主要包括三个销毁途径,按照如下执行顺序:
- @PreDestroy 注解,主要通过 DestructionAwareBeanPostProcessor 实现
- 实现 DisposableBean 接口,主要通过 DisposableBean.destroy() 实现
- 自定义销毁方 DisposableBeanAdapter.invokeCustomDestroyMethod() 实现