9. 生命周期
通常意义上讲的 bean 的生命周期,指的是 bean 从创建到初始化,经过一系列的流程,最终销毁的过程。只不过,在 Spring 中,bean 的生命周期是由 Spring 容器来管理的。在 Spring 中,我们可以自己来指定 bean 的初始化和销毁的方法。我们指定了 bean 的初始化和销毁方法之后,当容器在 bean 进行到当前生命周期的阶段时,会自动调用我们自定义的初始化和销毁方法。
9.1 XML方式
在标签中指定bean的初始化和销毁方法
<bean id="person" class="com.meimeixia.bean.Person" init-method="init" destroy-method="destroy">
<property name="age" value="18"></property>
<property name="name" value="liayun"></property>
</bean>
在我们自己写的Person类中,需要存在init()方法和destroy()方法。而且Spring中还规定,这里的init()方法和destroy()方法必须是无参方法,但可以抛出异常。
9.2 @Bean 注解方式
通过 @Bean 注解指定初始化和销毁方法。
在 MainConfig 配置类的 @Bean 注解中指定 initMethod 属性和 destroyMethod 属性
@Configuration
public class MainConfig {
@Bean(initMethod = "",destroyMethod = "")
public Person person() {
return new Person("zhangsan", 20);
}
}
在Spring容器中,先是调用了Car类的构造方法来创建Car对象,接下来便是调用了Car对象的init()方法来进行初始化。
bean的销毁方法是在容器关闭的时候被调用的。
@Test
public void test() {
// 创建IOC容器
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
System.out.println("容器创建完成");
// 关闭容器
applicationContext.close();
}
使用场景
数据源的管理
在配置数据源时,在初始化的时候,会对很多的数据源的属性进行赋值操作;
在销毁的时候,我们需要对数据源的连接等信息进行关闭和清理。
这个时候,我们就可以在自定义的初始化和销毁方法中来做这些事情了!
调用时机
初始化方法和销毁方法是在什么时候被调用的呢?
- 初始化方法:对象创建完成,如果对象中存在一些属性,并且这些属性也都赋好值之后,那么就会调用 bean 的初始化方法。
- 对于单实例 bean 来说,在 Spring 容器创建完成后,Spring 容器会自动调用 bean 的初始化方法;
- 对于多实例 bean 来说,在每次获取 bean 对象的时候,调用 bean 的初始化方法。
- 销毁方法
- 对于单实例 bean 来说,在容器关闭的时候,会调用 bean 的销毁方法;
- 对于多实例 bean 来说,Spring 容器不会管理这个 bean,也就不会自动调用这个 bean 的销毁方法了。不过,小伙伴们可以手动调用多实例 bean 的销毁方法。
9.3 InitializingBean 接口
接口概述
Spring 中提供了一个 InitializingBean 接口,该接口为 bean 提供了属性初始化后的处理方法,它只包括 afterPropertiesSet 方法,凡是继承该接口的类,在 bean 的属性初始化后都会执行该方法。
InitializingBean 接口的源码如下所示
package org.springframework.beans.factory;
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
根据 InitializingBean 接口中提供的 afterPropertiesSet() 方法的名字不难推断出,afterPropertiesSet() 方法是在属性赋好值之后调用的。
调用时机
我们定位到 Spring 中的 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 这个类里面的 invokeInitMethods() 方法中,来查看 Spring 加载 bean 的方法。
我们来到 AbstractAutowireCapableBeanFactory 类中的 invokeInitMethods() 方法处,如下所示。
package org.springframework.beans.factory.support;
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd) throws Throwable {
// 判断 bean 是否实现了 InitializingBean 接口
// 如果实现了 就调用 bean 的 afterPropertiesSet 方法
boolean isInitializingBean = bean instanceof InitializingBean;
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() throws Exception {
// 调用 bean 的 afterPropertiesSet 方法
((InitializingBean)bean).afterPropertiesSet();
return null;
}
}, this.getAccessControlContext());
} catch (PrivilegedActionException var6) {
throw var6.getException();
}
} else {
// 调用 bean 的 afterPropertiesSet 方法
((InitializingBean)bean).afterPropertiesSet();
}
}
if (mbd != null) {
String initMethodName = mbd.getInitMethodName();
if (initMethodName != null && (!isInitializingBean || !"afterPropertiesSet".equals(initMethodName)) && !mbd.isExternallyManagedInitMethod(initMethodName)) {
// 通过反射调用 init-Method
this.invokeCustomInitMethod(beanName, bean, mbd);
}
}
}
}
分析上述代码后,我们可以初步得出如下信息:
- Spring 为 bean 提供了两种初始化的方式
- 实现 InitializingBean 接口(也就是要实现该接口中的 afterPropertiesSet 方法)
- 在配置文件或 @Bean 注解中通过 init-method 来指定
- 两种方式可以同时使用,同时使用先调用 afterPropertiesSet 方法,后执行 init-method 指定的方法。
- 实现 InitializingBean 接口是直接调用 afterPropertiesSet() 方法,与通过反射调用 init-method 指定的方法相比,效率相对来说要高点。但是 init-method 方式消除了对 Spring 的依赖。
- 如果调用 afterPropertiesSet 方法时出错,那么就不会调用 init-method 指定的方法了。
9.4 DisposableBean 接口
接口概述
实现 org.springframework.beans.factory.DisposableBean 接口的 bean 在销毁前,Spring 将会调用 DisposableBean 接口的 destroy() 方法。也就是说我们可以实现 DisposableBean 这个接口来定义咱们这个销毁的逻辑。
我们先来看下 DisposableBean 接口的源码
package org.springframework.beans.factory;
public interface DisposableBean {
void destroy() throws Exception;
}
可以看到,在 DisposableBean 接口中只定义了一个 destroy() 方法。
在 bean 生命周期结束前调用 destroy()方法做一些收尾工作,亦可以使用 destroy-method。
- DisposableBean 接口与 Spring 耦合高,使用类型强转. 方法名 (),效率高;
- destroy-method 方法与 Spring 耦合低,使用反射,效率相对来说较低。
- 两个方法同时使用,先调用 DisposableBean 接口中的方法,再调用 destroy-method 方法
注意事项
多实例 bean 的生命周期不归 Spring 容器来管理,这里的 DisposableBean 接口中的方法是由 Spring 容器来调用的,所以如果一个多实例 bean 实现了 DisposableBean 接口是没有啥意义的,因为相应的方法根本不会被调用,当然了,在 XML 配置文件中指定了 destroy 方法,也是没有任何意义的。所以,在多实例 bean 情况下,Spring 是不会自动调用 bean 的销毁方法的。
9.5 @PostConstruct 注解
注解概述
@PostConstruct 注解好多人以为是 Spring 提供的,其实它是 Java 自己的注解,是 JSR-250 规范里面定义的一个注解。我们来看下 @PostConstruct 注解的源码
package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
从源码可以看出,@PostConstruct 注解是 Java 中的注解,并不是 Spring 提供的注解。
调用顺序
通常我们是会在 Spring 框架中使用到 @PostConstruct 注解的,该注解的方法在整个 bean 初始化中的执行顺序如下
- Constructor(构造方法)
- @Autowired(依赖注入)
- @PostConstruct(注释的方法)
- 实现了 InitializingBean 接口的 afterPropertiesSet() 方法。
- 最后,如果 bean 在配置中指定了 init() 方法,Spring 会调用该方法。
使用方法
public class Car implements InitializingBean, DisposableBean {
public Car() {
System.out.println("car constructor...");
}
@PostConstruct
public void init1(){
System.out.println("PostConstruct...");
}
@PreDestroy
public void destory1(){
System.out.println("PreDestroy...");
}
}
9.6 @PreDestroy 注解
注解概述
@PreDestroy注解同样是Java提供的,它也是JSR-250规范里面定义的一个注解。看下它的源码
package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
调用顺序
在 Spring 容器关闭时,销毁 bean 的顺序如下:
- 首先,Spring 会调用被 @PreDestroy 注解修饰的方法。
- 接下来,Spring 会调用实现了 DisposableBean 接口的 destroy() 方法。
- 最后,如果 bean 在配置中指定了 destroy 方法,Spring 会调用该方法。
使用方法
public class Car implements InitializingBean, DisposableBean {
public Car() {
System.out.println("car constructor...");
}
@PostConstruct
public void init1(){
System.out.println("PostConstruct...");
}
@PreDestroy
public void destory1(){
System.out.println("PreDestroy...");
}
}
9.7 BeanPostProcessor
1. 后置处理器概述
看下 BeanPostProcessor 的源码
package org.springframework.beans.factory.config;
import org.springframework.beans.BeansException;
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
}
从源码可以看出,BeanPostProcessor 是一个接口,其中有两个方法,即 postProcessBeforeInitialization 和 postProcessAfterInitialization 这两个方法,这两个方法分别是在 Spring 容器中的 bean 初始化前后执行,所以 Spring 容器中的每一个 bean 对象初始化前后,都会执行 BeanPostProcessor 接口的实现类中的这两个方法。
也就是说,postProcessBeforeInitialization 方法会在 bean 实例化和属性设置之后,自定义初始化方法之前被调用,而 postProcessAfterInitialization 方法会在自定义初始化方法之后被调用。当容器中存在多个 BeanPostProcessor 的实现类时,会按照它们在容器中注册的顺序执行。对于自定义的 BeanPostProcessor 实现类,还可以让其实现 Ordered 接口自定义排序。
因此我们可以在每个 bean 对象初始化前后,加上自己的逻辑。实现方式是自定义一个 BeanPostProcessor 接口的实现类,例如 MyBeanPostProcessor,然后在该类的 postProcessBeforeInitialization 和 postProcessAfterInitialization 这俩方法中写上自己的逻辑。
2. 使用方法
创建一个MyBeanPostProcessor类,实现BeanPostProcessor接口,如下所示。
package com.atguigu.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 后置处理器,在初始化前后进行处理工作
*
* @author longlong
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
}
测试一下
@Test
public void testInitial(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig1.class);
String[] definitionNames = applicationContext.getBeanDefinitionNames();
for (String name : definitionNames) {
System.out.println(name);
}
applicationContext.close();
}
3. 执行顺序
- Constructor(构造方法)
- @Autowired(依赖注入)
- 后置处理器 初始化前方法 postProcessBeforeInitialization
- @PostConstruct(注释的方法)
- 实现了 InitializingBean 接口的 afterPropertiesSet() 方法。
- bean 在配置中指定的 init() 方法
- 后置处理器 初始化后方法 postProcessAfterInitialization
4. 多个后置处理器顺序
Spring 容器中可以存在多个后置处理器,当容器初始化 bean 时,会按照这些后置处理器的执行顺序依次调用它们的 postProcessBeforeInitialization() 和 postProcessAfterInitialization() 方法。
实现了 Ordered 接口的后置处理器可以通过 getOrder() 方法返回一个整数值,表示其执行顺序的优先级,数值越小,优先级越高,即越先执行。如果不实现 Ordered 接口,默认的执行顺序为 Integer.MAX_VALUE。
package com.atguigu.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 后置处理器,在初始化前后进行处理工作
*
* @author longlong
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("My "+"postProcessBeforeInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("My "+"postProcessAfterInitialization..." + beanName + "=>" + bean);
return bean;
}
@Override
public int getOrder() {
return 3;
}
}
5. Spring 提供的实现类
后置处理器可用于 bean 对象初始化前后进行逻辑增强。Spring 提供了 BeanPostProcessor 接口的很多实现类
- ApplicationContextAwareProcessor 向组件中注入IOC容器
- AnnotationAwareAspectJAutoProxyCreator 用于 Spring AOP 的动态代理
- BeanValidationPostProcessor 用来为bean进行校验操作
- InitDestroyAnnotationBeanPostProcessor 处理 @PostConstruct 注解和 @PreDestroy 注解
- AutowiredAnnotationBeanPostProcessor 用于 @Autowired 注解的实现
ApplicationContextAwareProcessor
org.springframework.context.support.ApplicationContextAwareProcessor 是 BeanPostProcessor 接口的一个实现类,这个类的作用是可以向组件中注入IOC容器
大致的源码如下所示
package org.springframework.context.support;
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;
/**
* Create a new ApplicationContextAwareProcessor for the given context.
*/
public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}
@Override
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
AccessControlContext acc = null;
if (System.getSecurityManager() != null &&
(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}
if (acc != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareInterfaces(bean);
return null;
}
}, acc);
}
else {
invokeAwareInterfaces(bean);
}
return bean;
}
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
return bean;
}
}
要想使用ApplicationContextAwareProcessor类向组件中注入IOC容器,我们就不得不提Spring中的另一个接口了,即ApplicationContextAware。如果需要向组件中注入IOC容器,那么可以让组件实现ApplicationContextAware接口。
例如,我们创建一个 Dog 类,使其实现 ApplicationContextAware 接口,此时,我们需要实现 ApplicationContextAware 接口中的 setApplicationContext()方法,在 setApplicationContext() 方法中有一个 ApplicationContext 类型的参数,这个就是 IOC 容器对象,我们可以在 Dog 类中定义一个 ApplicationContext 类型的成员变量,然后在 setApplicationContext() 方法中为这个成员变量赋值,此时就可以在 Dog 类中的其他方法中使用 ApplicationContext 对象了
package com.atguigu.bean;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Cat implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
AnnotationAwareAspectJAutoProxyCreator
用于 Spring AOP 的动态代理
我们都知道 spring AOP 的实现原理是动态代理,最终放入容器的是代理类的对象,而不是 bean 本身的对象,那么 Spring 是什么时候做到这一步的呢?就是在 AnnotationAwareAspectJAutoProxyCreator 后置处理器的 postProcessAfterInitialization 方法中,即 bean 对象初始化完成之后,后置处理器会判断该 bean 是否注册了切面,若是,则生成代理对象注入到容器中。这一部分的关键代码是在哪儿呢?我们定位到 AbstractAutoProxyCreator 抽象类中的 postProcessAfterInitialization 方法处便能看到了,如下所示。
/**
* 在 bean 初始化后进行处理的方法。
*
* @param bean 初始化后的 bean 实例
* @param beanName bean 的名称
* @return 处理后的 bean 实例
* @throws BeansException 如果处理过程中发生异常
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 如果 bean 不为 null
if (bean != null) {
// 获取 bean 的缓存键
Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
// 如果缓存中不包含这个 bean 的早期代理引用
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 对 bean 进行包装处理,如果需要的话
return this.wrapIfNecessary(bean, beanName, cacheKey);
}
}
// 返回处理后的 bean 实例
return bean;
}
BeanValidationPostProcessor
org.springframework.validation.beanvalidation.BeanValidationPostProcessor类主要是用来为bean进行校验操作的,当我们创建bean,并为bean赋值后,我们可以通过BeanValidationPostProcessor类为bean进行校验操作。
BeanValidationPostProcessor类的源码
package org.springframework.validation.beanvalidation;
import java.util.Iterator;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class BeanValidationPostProcessor implements BeanPostProcessor, InitializingBean {
private Validator validator;
private boolean afterInitialization = false;
/**
* Set the JSR-303 Validator to delegate to for validating beans.
* <p>Default is the default ValidatorFactory's default Validator.
*/
public void setValidator(Validator validator) {
this.validator = validator;
}
/**
* Set the JSR-303 ValidatorFactory to delegate to for validating beans,
* using its default Validator.
* <p>Default is the default ValidatorFactory's default Validator.
* @see javax.validation.ValidatorFactory#getValidator()
*/
public void setValidatorFactory(ValidatorFactory validatorFactory) {
this.validator = validatorFactory.getValidator();
}
/**
* Choose whether to perform validation after bean initialization
* (i.e. after init methods) instead of before (which is the default).
* <p>Default is "false" (before initialization). Switch this to "true"
* (after initialization) if you would like to give init methods a chance
* to populate constrained fields before they get validated.
*/
public void setAfterInitialization(boolean afterInitialization) {
this.afterInitialization = afterInitialization;
}
@Override
public void afterPropertiesSet() {
if (this.validator == null) {
this.validator = Validation.buildDefaultValidatorFactory().getValidator();
}
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!this.afterInitialization) {
doValidate(bean);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (this.afterInitialization) {
doValidate(bean);
}
return bean;
}
/**
* Perform validation of the given bean.
* @param bean the bean instance to validate
* @see javax.validation.Validator#validate
*/
protected void doValidate(Object bean) {
Set<ConstraintViolation<Object>> result = this.validator.validate(bean);
if (!result.isEmpty()) {
StringBuilder sb = new StringBuilder("Bean state is invalid: ");
for (Iterator<ConstraintViolation<Object>> it = result.iterator(); it.hasNext();) {
ConstraintViolation<Object> violation = it.next();
sb.append(violation.getPropertyPath()).append(" - ").append(violation.getMessage());
if (it.hasNext()) {
sb.append("; ");
}
}
throw new BeanInitializationException(sb.toString());
}
}
}
在 postProcessBeforeInitialization()方法和 postProcessAfterInitialization() 方法都会根据 afterInitialization 这个布尔类型的成员变量的值来判断是否执行校验操作。
- 如果 afterInitialization 的值为 false,则在 postProcessBeforeInitialization()方法中调用 doValidate() 方法对 bean 进行校验;
- 如果 afterInitialization 的值为 true,则在 postProcessAfterInitialization()方法中调用 doValidate() 方法对 bean 进行校验。
InitDestroyAnnotationBeanPostProcessor
org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor 类主要用来处理 @PostConstruct 注解和 @PreDestroy 注解
源码分析
package org.springframework.beans.factory.annotation;
@SuppressWarnings("serial")
public class InitDestroyAnnotationBeanPostProcessor
implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor, PriorityOrdered, Serializable {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
try {
metadata.invokeInitMethods(bean, beanName);
}
catch (InvocationTargetException ex) {
throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
AutowiredAnnotationBeanPostProcessor
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor类主要是用于处理标注了@Autowired注解的变量或方法。
AutowiredAnnotationBeanPostProcessor 是 Spring 框架中的一个核心类,其主要作用是处理 @Autowired 注解,实现自动装配(autowiring)的功能。
具体来说,AutowiredAnnotationBeanPostProcessor 主要完成以下几个任务:
- 处理 @Autowired 注解:扫描容器中的 bean,找到标注了 @Autowired 注解的字段、构造方法、setter 方法等,并尝试自动装配这些标注了 @Autowired 注解的元素。
- 解析依赖:根据 @Autowired 注解指定的依赖查找策略(例如 byType、byName 等),自动解析和注入依赖。
- 处理 @Value 注解:除了处理 @Autowired 注解外,AutowiredAnnotationBeanPostProcessor 还处理 @Value 注解,用于从外部配置文件中读取属性值并注入到 bean 中。
- 实现 Aware 接口:AutowiredAnnotationBeanPostProcessor 本身也是一个 BeanPostProcessor,因此可以在 bean 初始化前后执行一些额外的处理工作,例如对 bean 进行校验、增强、代理等。
6. 底层原理
populateBean(beanName, mbd, instanceWrapper); // 给bean进行属性赋值
initializeBean(beanName, exposedObject, mbd)
{
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
invokeInitMethods(beanName, wrappedBean, mbd); // 执行自定义初始化
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
在 Spring 中,调用 initializeBean()方法之前,调用了 populateBean() 方法为 bean 的属性赋值,为 bean 的属性赋好值之后,再调用 initializeBean() 方法进行初始化。
在 initializeBean()中,调用自定义的初始化方法(即 invokeInitMethods())之前,调用了 applyBeanPostProcessorsBeforeInitialization()方法,而在调用自定义的初始化方法之后,又调用了 applyBeanPostProcessorsAfterInitialization() 方法。至此,整个 bean 的初始化过程就这样结束了。