Spring框架提供了丰富的扩展点,允许开发者在bean的生命周期的不同阶段插入自定义逻辑,从而增强应用的功能和灵活性。拓展点包括BeanFactoryPostProcessorBeanPostProcessor、各种Aware等。下面来具体讲解各个拓展点的作用以及它们是如何介入到bean 的生命周期中。

除了Aware接口和BeanPostProcessor,还有许多其他扩展点,如BeanFactoryPostProcessorApplicationListenerInitializingBeanFactoryBean等。这些扩展点的合理使用可以极大地提高Spring应用的可扩展性和可维护性。

1.BeanFactoryPostProcessor

BeanFactoryPostProcessor 是 Spring 框架中的一个函数式接口,它在bean 开始整个创建流程之前 起作用。

通过实现该接口可以在 Bean 开始整个创建流程之前读取 BeanFactory 中的 BeanDefinition 并进行修改,比如调整 Bean 的属性、依赖关系等定义。

Spring 自带了一些 BeanFactoryPostProcessor 的实现,用户也可以根据需要自定义实现以适应特定场景,从而实现更灵活的应用配置。

1
2
3
4
5
@FunctionalInterface  
public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

1.1 注册时机 and 作用过程-invokeBeanFactoryPostProcessors

前面说到BeanFactoryPostProcessor 是 Spring 框架在bean 开始整个创建流程之前 起作用。具体的位置如下,位于refresh 中的invokeBeanFactoryPostProcessors 方法中, 通过invoke 这个命名就可以知道这里需要调用所有BeanFactoryPostProcessor 的具体实现逻辑对bean 定义进行修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {

// 1. 创建beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 2.BeanFactoryPostProcessor起作用
invokeBeanFactoryPostProcessors(beanFactory);

// 3.注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory);

// 4. bean的生命周期管理和依赖关系的装配
finishBeanFactoryInitialization(beanFactory);
}

执行BeanFactoryPostProcessor逻辑前, 需要有BeanFactoryPostProcessor的实例,那么BeanFactoryPostProcessor是如何实例化的呢, 下面来看下 BeanFactoryPostProcessor 的实例化和具体起作用的过程

先进入

1
2
3
AbstractApplicationContext.java
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

再进入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors的方法,可以看到此时传进来了3个BeanFactoryPostProcessor,这3个BeanFactoryPostProcessor 是在应用上下文ApplicationContext 里面存储维护的,但是此时还没有看到自定义的

来看一下PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors 的具体处理逻辑.BeanFactoryPostProcessors将bean 分成了好几类分别进行处理,

1.2 BeanDefinitionRegistryPostProcessor

1
2
3
4
5
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {  

void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

BeanDefinitionRegistryPostProcessor 继承了BeanFactoryPostProcessor , 并增加了一个方法, 在执行BeanFactoryPostProcessor 前,需要找出所有的BeanDefinitionRegistryPostProcessor, 并且先执行自己的postProcessBeanDefinitionRegistry方法,再执行继承来的postProcessBeanFactory 方法。
看以下重点代码,BeanDefinitionRegistryPostProcessor包括参数中传进来来的和从beanFactory 中找到的, 其中从beanFactory找到的BeanDefinitionRegistryPostProcessor,还没有进行实例化,需要实例化后才能使用,这个实例化的过程和业务bean 的实力化过程是同一个

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
if (beanFactory instanceof BeanDefinitionRegistry) {  
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 从传参中找到 BeanDefinitionRegistryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
// 从beanFactory 中找到BeanDefinitionRegistryPostProcessor并进行实例化
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
}
}
//先执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//再执行BeanFactoryPostProcessor的postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
}

1.3 执行顺序- Ordered

在invoke 完BeanDefinitionRegistryPostProcessor后,就开始按照优先级顺序处理BeanFactoryPostProcessor。

Spring提供了一些机制来管理多个BeanFactoryPostProcessor的执行顺序,其执行顺序分别是

  1. PriorityOrdered 接口
  2. 优先级接口 Ordered
  3. NonOrdered

1.3.1 优先级接口 Ordered

Spring允许BeanFactoryPostProcessor实现Ordered接口来指定执行顺序。Ordered接口要求实现一个方法getOrder(),该方法返回一个整数,定义了BeanFactoryPostProcessor的执行顺序。数值越小,优先级越高,越优先执行

例如,以下是一个BeanFactoryPostProcessor实现,它使用了Ordered接口来指定其执行顺序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 获取名为 "myBean" 的 BeanDefinitionBeanDefinition
beanDefinition = beanFactory.getBeanDefinition("myBean");

// 修改 "myBean" 的属性值
beanDefinition.getPropertyValues().add("name", "Modified by BeanFactoryPostProcessor");
}

@Override
public int getOrder() {
return 10; // 数值越小,优先级越高
}
}

1.3.2 PriorityOrdered 接口

PriorityOrderedOrdered接口的一个子接口,允许BeanFactoryPostProcessor在其他普通Ordered执行。这主要用于那些必须首先应用的处理器,比如那些涉及配置如何加载的处理器。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class CustomPriorityOrderedBeanFactoryPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered {  

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 定制处理逻辑
System.out.println("Executing CustomPriorityOrderedBeanFactoryPostProcessor");
}

@Override
public int getOrder() {
return 5; // 数值越小,优先级越高
}
}

1.3.3 NonOrdered

NonOrdered并不是一个接口,指的是没有实现Ordered 或者 PriorityOrdered 的 BeanFactoryPostProcessor, 它会放在最后执行。

所以,综上,在Spring容器启动过程中,BeanFactoryPostProcessor的调用顺序如下:

  • 首先,实现PriorityOrderedBeanFactoryPostProcessor按照它们的顺序值被调用。
  • 其次,实现Ordered接口的普通BeanFactoryPostProcessor按照它们的顺序值被调用。
  • 最后,未实现任何排序接口的BeanFactoryPostProcessor按照它们的注册顺序被调用。

1.3.4 处理逻辑

在invoke 完BeanDefinitionRegistryPostProcessor后,就开始按照优先级顺序处理BeanFactoryPostProcessor。 代码逻辑会先找出所有的BeanFactoryPostProcessor, 然后将其分类为PriorityOrderedBeanFactoryPostProcessorOrderedBeanFactoryPostProcessorNonOrderedBeanFactoryPostProcessor, 并按照优先级顺序分别invoke postProcessBeanFactory 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public static void invokeBeanFactoryPostProcessors(  
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 找出所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 分类
for (String ppName : postProcessorNames) {
// processedBeans保存已处理的BeanFactoryPostProcessor 名称
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// orderedPostProcessor 在后面也会通过getBean实例化,逻辑比较简单,我省略了,nonOrderedPostProcessor同理
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// 分别invoke postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
}

1.4 BeanFactoryPostProcessor也是bean

无论是 BeanDefinitionRegistryPostProcessor,还是BeanFactoryPostProcessor, 在通过getBeanNamesForType获取名称后,invoke postProcessBeanFactory 方法之前,需要先进行实例化操作(都要调用方法了,肯定要有对象存在啊)。 BeanFactoryPostProcessor 的实例化过程和业务bean 的实例化过程 完全相同,都是getBean流程完成实例化操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 实例化 BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));


// 实例化 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));

orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));

nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));

2.BeanPostProcessor

BeanPostProcessor是Spring框架中一个非常强大的扩展点,提供的一个接口,用于在bean的init操作前后执行自定义逻辑。Spring AOP就是通过BeanPostProcessor实现的

BeanPostProcessor也是一个接口,包含2个方法

  • postProcessBeforeInitialization: 在bean init之前执行。
  • postProcessAfterInitialization: 在bean init 之后执行。
1
2
3
4
5
public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

2.1 注册时机-registerBeanPostProcessors

依然回到refresh方法中 ,其中registerBeanPostProcessors 方法涉及到BeanPostProcessor的注册流程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
AbstractApplicationContext.java
@Override
public void refresh() throws BeansException, IllegalStateException {

// 1. 创建beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 2.BeanFactoryPostProcessor起作用
invokeBeanFactoryPostProcessors(beanFactory);

// 3.注册 BeanPostProcessor
registerBeanPostProcessors(beanFactory);

// 4. bean的生命周期管理和依赖关系的装配
finishBeanFactoryInitialization(beanFactory);
}

进入registerBeanPostProcessors分析具体代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

PostProcessorRegistrationDelegate.java

public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 找出所有 BeanPostProcessor 名称
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//按照优先级别 对BeanPostProcessor 名称
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);

}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
// orderedPostProcessor 在后面也会通过getBean 实例化,逻辑比较简单,我省略了,nonOrderedPostProcessor同理
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
}

可以看到registerBeanPostProcessors 的整理流程比较类似,都是

  1. 用beanFactory.getBeanNamesForType找出所有名字
  2. 分类
  3. getBean 实例化

一个比较明显的区别是 BeanFactoryPostProcessor在实例化后会直接调用接口postProcessBeanFactory执行逻辑,但是BeanPostProcessor 的实例只会先添加到beanFactory 中,等到业务bean的init 阶段才会执行逻辑。

由此可见 注册BeanFactoryPostProcessor 用到的是invokeBeanFactoryPostProcessorsBeanPostProcessor 只是registerBeanPostProcessors, 这里的方法命名还是相当准确的

2.2 执行顺序-Ordered

从上面的代码中可以看到 Spring 管理多个BeanPostProcessor的执行顺序,其实现和BeanFactoryPostProcessor 完全一致,

  1. PriorityOrdered 接口
  2. 优先级接口 Ordered
  3. NonOrdered

这里给出一些实际代码示例就不再赘述了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

public class MyBeanPostProcessor implements BeanPostProcessor, Ordered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 自定义逻辑
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 自定义逻辑
return bean;
}

@Override
public int getOrder() {
return 10; // 返回一个数值来指定执行顺序
}
}


public class PriorityLoggingBeanPostProcessor implements BeanPostProcessor, PriorityOrdered {

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 在bean初始化之前打印日志
System.out.println("Before Initializing Bean '" + beanName + "': " + bean.getClass().getSimpleName());
return bean;
}

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 初始化后的处理可以在这里添加,此示例仅在初始化前打印
return bean;
}

@Override
public int getOrder() {
// 返回值较低表示优先级较高,此处返回最高优先级
return PriorityOrdered.HIGHEST_PRECEDENCE;
}
}

2.3 BeanPostProcessor也是bean

通过registerBeanPostProcessors 代码可知, BeanPostProcessorBean FactoryPostProcessor 一样, 通过getbean 进行实例化的

1
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); 

并在实例化后添加到beanFactory 中进行管理

1
2
3
4
5
6
7
8
PostProcessorRegistrationDelegate.java

private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}

2.4 Spring 启动过程中会用到的 BeanPostProcessor

2.4.1 InstantiationAwareBeanPostProcessor

图中置灰的2个方法,是继承自BeanPostProcessor的2个方法

InstantiationAwareBeanPostProcessor自有的3个方法中有2个方法名称和BeanPostProcessor中方式名称相同,但是入参和返回值略有不同

  1. postProcessBeforeInstantiation
    1
    2
    3
    4
    @Nullable  
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    return null;
    }

在bean 的实例化之前,会调用这个方法,其逻辑存在于下面代码中resolveBeforeInstantiation方法中。 这个方法可以返回一个代理对象,来替代 Bean 的默认实例化过程。但通常情况下,代理对象是在 Bean 实例化之后创建的,所以这个方法一般返回 null

1
2
3
4
5
6
7
8
9
10
11
@Override  
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
Object beanInstance = doCreateBean(beanName, mbdToUse, args);


}
  1. postProcessAfterInstantiation
    在 bean create之后,populate之前调用。返回 true 表示允许属性注入,返回 false 则跳过属性注入。
1
2
3
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {  
return true;
}
  1. postProcessProperties
    在populate 属性注入过程中调用,可以对属性值进行检查或修改。
    1
    2
    3
    4
    5
    @Nullable  
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    throws BeansException {
    return null;
    }

2.4.2 SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor 是 Spring 框架中的一个接口,它扩展了 InstantiationAwareBeanPostProcessor 接口,提供了更细粒度的控制和额外的钩子方法来介入 Spring Bean 的实例化过程。这个接口主要用于在 Bean create之前、create之后、populate之前、populate之后等多个阶段执行自定义逻辑,从而实现更加复杂和灵活的 Bean 初始化控制。

  1. predictBeanType
    在实际创建 Bean 实例之前预测其类型。这对于提前检测某些类型相关的元数据很有用。
    1
    2
    3
    default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {  
    return null;
    }
  1. determineCandidateConstructors
    确定要用于创建 Bean 实例的候选构造函数。允许自定义选择用于实例化 Bean 的构造函数。

    1
    2
    3
    4
    5
    default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)  
    throws BeansException {

    return null;
    }
  2. getEarlyBeanReference
    允许在 Bean 实例化之前提前暴露 Bean 的引用。通常用于解决循环依赖问题

    1
    2
    3
    default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {  
    return bean;
    }

2.5 BeanFactoryPostProcessor vs BeanPostProcessor

BeanFactoryPostProcessorBeanPostProcessor名称相似,但是作用大不相同,下面给出一些对比

为了更清楚地比较 BeanFactoryPostProcessorBeanPostProcessor,下表总结了它们的关键差异:

特征 BeanFactoryPostProcessor BeanPostProcessor
目的 修改或调整 bean 的配置元数据 在 bean 初始化前后对实例进行修改或增强
作用对象 操作 BeanDefinition(bean 的定义) 直接操作 bean 实例
执行时机 在所有 bean 实例化前,容器启动过程中,加载完所有 bean 定义之后执行 对每个 bean,分别在初始化Initialization方法之前和之后执行
方法接口 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) postProcessBeforeInitialization(Object bean, String beanName)
postProcessAfterInitialization(Object bean, String beanName)
影响范围 可以修改整个容器中的所有 bean 定义 对每个 bean 实例的修改是独立的
应用示例 修改 bean 的作用域、解析配置文件中的占位符等 创建代理对象以实现 AOP,执行自定义初始化或清理代码等
执行顺序控制接口 通常可以通过实现 OrderedPriorityOrdered 接口来控制执行顺序 同样可以实现 OrderedPriorityOrdered 来控制执行顺序

3. 无所不知的Aware

Spring框架中,Aware接口的作用是让bean能够拿到对Spring容器中的各种资源,从而增强bean的功能和灵活性。

不同的 Aware 基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如BeanNameAware可以拿到BeanName,以此类推。调用时机需要注意:所有的Aware方法都是在init阶段之前调用的

3.1 Aware调用时机

在Spring 启动过程中涉及到Aware ,都是在populate后,init 之前调用的。

其调用代码如下,

1
2
3
4
5
6
7
8
9
10
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {  
// 调用 bean 相关的 Aware
invokeAwareMethods(beanName, bean);
// 调用 ApplicationContext 的相关 Aware
applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

invokeInitMethods(beanName, wrappedBean, mbd);

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

在Spring 中一些会用到Aware 列举如下, 这也是在实际运行中它们会被调用的顺序

  1. BeanNameAware: 最先被调用,用于设置bean的名称。
  2. BeanClassLoaderAware: 在bean实例化后,用于设置bean的类加载器。
  3. BeanFactoryAware: 在bean populate 完成后,用于设置bean的BeanFactory。
  4. EnvironmentAware: 在bean的populate 完成后,用于设置bean的环境信息。
  5. EmbeddedValueResolverAware: 在bean的populate 完成后,用于设置Spring EL解析器。
  6. ApplicationContextAware: 最后被调用,用于设置bean的ApplicationContext。

下面将分组进行解释

3.2 Aware Group 1- Bean 相关Aware

在invokeAwareMethods方法中,会调用以下3个Aware

  • BeanNameAware: 用于让bean获取其在容器中的名称。在实例化之后,设置依赖之前被调用。
  • BeanClassLoaderAware: 用于让bean获取类加载器。这通常在bean实例化之后和依赖注入之前被调用。
  • BeanFactoryAware: 用于让bean获取它所在的BeanFactory实例。在依赖注入之后,bean初始化之前被调用。

点击查看invokeAwareMethods, 其逻辑涉及到3个Aware 接口

1.BeanFactoryAware

1
2
3
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
  • 作用:允许bean获取BeanFactory实例,从而能够访问Spring容器中的其他bean。
  • 使用场景:在需要动态获取或创建bean的场景下使用,例如实现复杂的依赖关系或自定义初始化逻辑。

2.BeanNameAware

1
2
3
public interface BeanNameAware {
void setBeanName(String name);
}

实现 BeanNameAware 接口的 bean 会在 Spring 容器创建并初始化该 bean 时,调用 setBeanName 方法,将容器中为该 bean 配置的名称传递给它。这对于需要知道自己在容器中的名称的 bean 来说非常有用。

3.3 Aware Group 2-ApplicationContext 相关Aware

并不是所有的Aware接口都使用同样的方式调用。Bean××Aware都是在代码中直接调用的,而ApplicationContext相关的Aware都是通过BeanPostProcessor#postProcessBeforeInitialization()实现的

  • EnvironmentAware: 允许bean访问Spring的Environment接口,用于获取环境属性和配置文件信息。
  • EmbeddedValueResolverAware: 允许bean获取Spring的字符串值解析器,特别是用来解析Spring EL表达式(SpEL)。
  • ApplicationContextAware: 允许bean获取ApplicationContext,这是BeanFactory的一个子接口,提供更多容器功能和应用上下文相关的信息。

跟进代码最后来到ApplicationContextAwareProcessor中,ApplicationContextAwareProcessor 是一个BeanPostProcessor, 最后在其重写的postProcessBeforeInitialization方法中,会调用如下方法。

3.4 Aware执行时机

1
2
3
4
5
6
7
8
9
10
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {  

invokeAwareMethods(beanName, bean);

applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

invokeInitMethods(beanName, wrappedBean, mbd);

applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.stereotype.Component;

@Component
public class MyBeanFactoryAwareBean implements BeanFactoryAware {

private BeanFactory beanFactory;

@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
System.out.println("BeanFactory has been set: " + beanFactory);
}

public void doSomething() {
// 使用beanFactory获取另一个bean
MyOtherBean otherBean = beanFactory.getBean(MyOtherBean.class);
otherBean.performTask();
}
}

4.Bean生命周期

对bean 的生命周期做细化的话可以分为以下阶段

  1. 实例化(Instantiation)

    • Spring容器使用构造函数或工厂方法实例化bean。
  2. 属性填充(Dependency Injection)

    • Spring容器进行依赖注入,将所有需要的属性和依赖注入到bean实例中。
  3. 设置特殊回调接口(Aware接口)

    • 如果bean实现了Aware接口,Spring容器会在这个阶段调用相应的方法。
    • 包括BeanNameAwareBeanClassLoaderAwareBeanFactoryAware等。
  4. 初始化前处理(BeanPostProcessor的postProcessBeforeInitialization方法)

    • Spring容器会在这个阶段调用所有注册的BeanPostProcessorpostProcessBeforeInitialization方法。
  5. 初始化(Initialization)

    • 如果bean实现了InitializingBean接口,Spring容器会调用其afterPropertiesSet方法。
    • 如果bean配置了自定义的init方法,Spring容器会调用该方法。
  6. 初始化后处理(BeanPostProcessor的postProcessAfterInitialization方法)

    • Spring容器会在这个阶段调用所有注册的BeanPostProcessorpostProcessAfterInitialization方法。