封面来源:碧蓝航线 逆转彩虹之塔 活动CG

本文基于 SpringBoot 3.1.x

1. 如何获取

一般来说,获取 ApplicationContext 有两种方式:

  1. 实现 ApplicationContextAware 接口,Spring 会在合适的时机回调 setApplicationContext() 方法,获取到 ApplicationContext 实例;
  2. 使用 @Autowired 注解直接注入 ApplicationContext 实例。

2. 注入 ApplicationContext

2.1 使用示例

1
2
3
4
5
6
7
8
9
10
@Component
static class MyApplicationContext {
private ApplicationContext applicationContext;

@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
System.out.println("1. 使用 @Autowired 注入 ApplicationContext");
}
}

Spring 容器启动过程中,控制台打印出:

1. 使用 @Autowired 注入 ApplicationContext

除了使用 Setter 注入,使用构造方法注入、字段注入也都是可以的。

ApplicationContext 虽然能够通过 @Autowired 注解注入到 Bean 中,但 ApplicationContext 本身并不是 Spring 容器中的一个 Bean,如果想通过 getBean(ApplicationContext.class) 方式获取 ApplicationContext,则会抛出 NoSuchBeanDefinitionException 异常,显示没有可用的 ApplicationContext 类型的 Bean。

2.2 为什么能注入 ApplicationContext

既然 Spring 容器中并不存在 ApplicationContext 类型的 Bean,那为什么又能通过 @Autowired 注解注入呢?

Spring 容器中的普通 Bean 元数据信息都是存放在 DefaultListableBeanFactory 中的,比如:

1
2
3
4
// BeanDefinition 集合,key 为 Bean 的名称
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 按注册顺序写入的 BeanDefinition 名称
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

ApplicationContext 也是存放在 DefaultListableBeanFactory 类中的,只不过放在 resolvableDependencies 中:

1
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);

resolvableDependencies 中存放的都是一些能够被 @Autowired 注解注入的依赖项,但不包含普通的 Bean。

在查找依赖(比如使用 @Autowired)时,会同时在 beanDefinitionNamesresolvableDependencies 搜索,因此能够注入 ApplicationContext;而 getBean 时,只会在 BeanDefinitionMap 中搜索,ApplicationContext 自然也就找不到了。

2.3 注册 ApplicationContext

ApplicationContext 在准备 BeanFactory 时就被加载了,实现逻辑在著名的 org.springframework.context.support.AbstractApplicationContext#refresh() 中:

1
2
3
4
5
6
7
8
9
10
11
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// --snip--

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

// --snip--
}
}

而在 prepareBeanFactory() 方法中有:

1
2
3
4
5
6
7
8
9
10
11
12
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// --snip--

// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

// --snip--
}

beanFactory.registerResolvableDependency() 方法用于设置依赖注入某种类型的对象,比如:

1
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);

当进行如下的依赖注入时:

1
2
@Autowired
private BeanFactory beanFactory;

实际注入的是 beanFactory.registerResolvableDependency() 方法的第二个参数,即 prepareBeanFactory() 方法的 beanFactory 参数。

再比如后面的三行表示注入 ResourceLoaderApplicationEventPublisherApplicationContext 时,注入的对象是 this,即:ApplicationContext

简单来说:通过 @Autowired 注解注入 BeanFactoryResourceLoaderApplicationEventPublisherApplicationContext

2.4 @Autowired 的实现

@Autowired 注解的实现离不开 AutowiredAnnotationBeanPostProcessor,它又是什么时候创建的、什么时候执行的呢?

以 SpringBoot 中最主要的 run() 方法为入口,org.springframework.boot.SpringApplication#run(java.lang.String...) 方法中的执行逻辑分为以下几步:

flowchart TD 
1("reateBootstrapContext()")
2("configureHeadlessProperty")
3("getRunListeners() & listeners.starting()")
4("prepareEnvironment()")
5("printBanner()")
subgraph 6 ["createApplicationContext()"]
6.1("注册 AutowiredAnnotationBeanPostProcessor 的 BeanDefinition"):::orange-red-filling
end
7("prepareContext()")
subgraph 8 ["refreshContext()"]
    direction TB
    8.1("实例化 AutowiredAnnotationBeanPostProcessor"):::orange-red-filling
    8.2("创建 Bean 时进行依赖注入"):::orange-red-filling
end
9("afterRefresh()")
10("listeners.started()")
11("callRunners()")
1 --> 2 --> 3 --> 4 --> 5 --> 6 --> 7 --> 8 --> 9 --> 10 --> 11
8.1 --> 8.2
classDef orange-red-filling fill:#f96;

注册 AutowiredAnnotationBeanPostProcessorBeanDefinition

在执行 createApplicationContext() 方法时,默认创建 AnnotationConfigApplicationContext

1
2
3
4
5
6
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

然后又会创建 AnnotatedBeanDefinitionReader

1
2
3
4
5
6
7
8
9
10
11
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

调用 AnnotationConfigUtils#registerAnnotationConfigProcessors() 方法时,将 AutowiredAnnotationBeanPostProcessorBeanDefinition 注册到容器中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
// --snip--
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// --snip--
}

从这段代码还能知道 AutowiredAnnotationBeanPostProcessor 对应的 beanName 是 AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME

1
2
public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor";

实例化 AutowiredAnnotationBeanPostProcessor

实例化是在 refreshContext() 方法中完成的,最终会来到 org.springframework.context.support.AbstractApplicationContext#refresh() 方法中:

1
2
3
4
5
6
7
8
9
10
11
12
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// --snip--

try {
// --snip--

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
}
}
}

真正的实例化工作委托给 PostProcessorRegistrationDelegate#registerBeanPostProcessors() 方法:

1
2
3
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

在该方法内部获取到所有的 BeanPostProcessor,然后按照优先级、不同的分类完成实例化。

依赖注入

以常见的单例 Bean 为例,单例 Bean 的初始化同样是在 org.springframework.context.support.AbstractApplicationContext#refresh() 方法中完成:

1
2
3
4
5
6
7
8
9
10
11
12
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// --snip--

try {
// --snip--

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
}
}
}

finishBeanFactoryInitialization() 方法中又调用了 preInstantiateSingletons() 方法:

1
2
3
4
5
6
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// --snip--

// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}

最终来到 DefaultListableBeanFactory#preInstantiateSingletons() 方法里:

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
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}

// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象的、是单例的、没有延迟加载
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 是工厂 Bean 走这
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
getBean(beanName);
}
}
else {
// 否则走这
getBean(beanName);
}
}
}

// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
StartupStep smartInitialize = this.getApplicationStartup().start("spring.beans.smart-initialize")
.tag("beanName", beanName);
smartSingleton.afterSingletonsInstantiated();
smartInitialize.end();
}
}
}

最终调用了 getBean() 方法:

1
2
3
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}

doGetBean() 中创建单例 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
25
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
// --snip--

// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
// 创建 Bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

// --snip--
}

创建 Bean 的 createBean() 方法最终会调用 AbstractAutowireCapableBeanFactory#createBean() 方法,而在该方法中又会调用 doCreateBean() 方法,总之就是套娃:

1
2
3
4
5
6
7
8
9
10
11
12
13
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// --snip--
try {
// 继续套娃
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
// --snip--
}

doCreateBean() 方法中完成单例 Bean 的初始化,初始化之前会调用 populateBean() 方法填充 Bean,也就是进行依赖注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// --snip--
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充 Bean:进行依赖注入
populateBean(beanName, mbd, instanceWrapper);
// 初始化 Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
throw bce;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
}
}
// --snip--
}

populateBean() 方法中会对所有 InstantiationAwareBeanPostProcessor 进行循环,调用它们的 postProcessProperties() 方法,而 AutowiredAnnotationBeanPostProcessor 就是它们中的一员:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
// --snip--
if (hasInstantiationAwareBeanPostProcessors()) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
pvs = pvsToUse;
}
}
// --snip--
}

AutowiredAnnotationBeanPostProcessorpostProcessProperties() 方法中,先获取到 InjectionMetadata(注入元数据),然后执行 inject() 方法完成注入:

1
2
3
4
5
6
7
8
9
10
11
12
13
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
metadata.inject(bean, beanName, pvs);
}
catch (BeanCreationException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
}
return pvs;
}

findAutowiringMetadata() 方法中会调用 buildAutowiringMetadata() 方法:

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
private InjectionMetadata buildAutowiringMetadata(Class<?> clazz) {
// --snip--

do {
final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

ReflectionUtils.doWithLocalFields(targetClass, field -> {
// 查看字段上是否有依赖注入相关的注解
MergedAnnotation<?> ann = findAutowiredAnnotation(field);
if (ann != null) {
if (Modifier.isStatic(field.getModifiers())) {
if (logger.isInfoEnabled()) {
logger.info("Autowired annotation is not supported on static fields: " + field);
}
return;
}
boolean required = determineRequiredStatus(ann);
// 添加 InjectedElement
currElements.add(new AutowiredFieldElement(field, required));
}
});

// 反射遍历方法
}
while (targetClass != null && targetClass != Object.class);

return InjectionMetadata.forElements(elements, clazz);
}

buildAutowiringMetadata() 方法内部使用反射遍历 Bean 中的每个字段和方法,查看它们是否有依赖注入相关的注解,这个逻辑由 findAutowiredAnnotation() 方法完成:

1
2
3
4
5
6
7
8
9
10
private MergedAnnotation<?> findAutowiredAnnotation(AccessibleObject ao) {
MergedAnnotations annotations = MergedAnnotations.from(ao);
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
MergedAnnotation<?> annotation = annotations.get(type);
if (annotation.isPresent()) {
return annotation;
}
}
return null;
}

this.autowiredAnnotationTypes 中的数据是构造 AutowiredAnnotationBeanPostProcessor 添加的,可以看到支持 @Autowired@Value@Inject 三种注解:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public AutowiredAnnotationBeanPostProcessor() {
this.autowiredAnnotationTypes.add(Autowired.class);
this.autowiredAnnotationTypes.add(Value.class);

try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("jakarta.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("'jakarta.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// jakarta.inject API not available - simply skip.
}

try {
this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
logger.trace("'javax.inject.Inject' annotation found and supported for autowiring");
}
catch (ClassNotFoundException ex) {
// javax.inject API not available - simply skip.
}
}

那注入的数据又是怎么来的呢?

回到 AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata() 方法中,如果字段上有依赖注入相关的注解,并且字段没有被 static 修饰,那么就会创建一个 AutowiredFieldElement 对象,最终使用 InjectionMetadata.forElements() 方法将所有的 AutowiredFieldElement 对象整合到 InjectionMetadata 对象中。

所有的 AutowiredFieldElement 对象被整合到 InjectionMetadatainjectedElements 字段中。

完成 InjectionMetadata 对象的组装后,回到 AutowiredAnnotationBeanPostProcessor#postProcessProperties() 方法中,接下来执行 inject() 方法完成依赖注入:

1
2
3
4
5
6
7
8
9
10
11
public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Collection<InjectedElement> checkedElements = this.checkedElements;
Collection<InjectedElement> elementsToIterate =
(checkedElements != null ? checkedElements : this.injectedElements);
if (!elementsToIterate.isEmpty()) {
// 遍历 injectedElements,依次执行 inject 方法
for (InjectedElement element : elementsToIterate) {
element.inject(target, beanName, pvs);
}
}
}

由于 injectedElements 中的元素包括 AutowiredFieldElement 类型,也就是会执行到 AutowiredFieldElementinject() 方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
// 有缓存的情况
if (this.cached) {
try {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
catch (NoSuchBeanDefinitionException ex) {
// Unexpected removal of target bean for cached argument -> re-resolve
value = resolveFieldValue(field, bean, beanName);
}
}
// 无缓存的情况
else {
value = resolveFieldValue(field, bean, beanName);
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}

假设并不存在缓存,那么执行 resolveFieldValue() 方法,在该方法中调用 BeanFactoryresolveDependency() 方法来获取依赖注入的值:

1
2
3
4
5
6
7
8
private Object resolveFieldValue(Field field, Object bean, @Nullable String beanName) {
// --snip--
Object value;
try {
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
// --snip--
}

接下来会进入 BeanFactory 的实现类 DefaultListableBeanFactory 中的 resolveDependency() 方法:

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 Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
// 是 Optional 类型
if (Optional.class == descriptor.getDependencyType()) {
return createOptionalDependency(descriptor, requestingBeanName);
}
// 是 ObjectFactory、ObjectProvider 类型
else if (ObjectFactory.class == descriptor.getDependencyType() ||
ObjectProvider.class == descriptor.getDependencyType()) {
return new DependencyObjectProvider(descriptor, requestingBeanName);
}
// 是 Provider 类型
else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
}
// 否则
else {
Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
descriptor, requestingBeanName);
if (result == null) {
result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
}
return result;
}
}

显然会进入最后一个分支,执行 doResolveDependency() 获取依赖注入的值,此方法内部会调用 findAutowireCandidates() 方法,获取依赖注入的候选值,根据候选值信息来到最终应该被依赖注入的值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
protected Map<String, Object> findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this, requiredType, true, descriptor.isEager());
Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);
// 从 resolvableDependencies 中获取
for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
// --snip--
}
// 从 BeanDefinitionNames 中寻找
for (String candidate : candidateNames) {
if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
addCandidateEntry(result, candidate, descriptor, requiredType);
}
}
// --snip--
}

至此证明 @Autowired 注解进行依赖注入时可以在 beanDefinitionNamesresolvableDependencies 搜索要被注入的值。

3. ApplicationContextAware 接口

3.1 接口介绍

ApplicationContextAware 接口是 Aware 接口的子接口,Aware 接口是一个标记接口,类似于 Serializable 接口。实现了 Aware 接口的 Bean 能够通过一个回调方法被 Spring 容器通知(这个“通知”通常用来设置一些 Spring 相关的信息,因此回调方法通常以 set 开头,具体内容由各子接口确定),比如 EnvironmentAwareApplicationEventPublisherAware 等接口,以及这里的 ApplicationContextAware 接口。

1
2
3
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

3.2 使用示例

1
2
3
4
5
6
7
8
9
10
@Component
static class MyApplicationContextAware implements ApplicationContextAware {
private ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
System.out.println("2. Spring 上下文 ApplicationContext 被注入");
}
}

Spring 容器启动过程中,控制台打印出:

2. Spring 上下文 ApplicationContext 被注入

3.3 源码分析

ApplicationContextAware 的执行与 ApplicationContextAwareProcessor 相关,ApplicationContextAwareProcessor 实现了 BeanPostProcessor 接口,该接口作为 Spring 的拓展点之一,能够在所有 Bean 初始化前和初始化后执行一些处理逻辑。

ApplicationContextAwareProcessor 只重写了 BeanPostProcessor 接口中的 postProcessBeforeInitialization() 方法,使得能够在所有 Bean 初始化前执行。

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
bean instanceof ApplicationStartupAware)) {
return bean;
}

invokeAwareInterfaces(bean);
return bean;
}

在重写的方法内部,首先判断当前 Bean 是否实现了一些 Aware 接口,如果没有实现,直接返回,反之执行 invokeAwareInterfaces() 方法。

1
2
3
4
5
6
7
8
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof Aware) {
// --snip--
if (bean instanceof ApplicationContextAware applicationContextAware) {
applicationContextAware.setApplicationContext(this.applicationContext);
}
}
}

invokeAwareInterfaces() 方法中根据不同的接口执行其中不同的方法。

ApplicationContextAwareProcessor 的加载时机

ApplicationContextAwareProcessor 在准备 BeanFactory 时就被加载了,实现逻辑同样是在 org.springframework.context.support.AbstractApplicationContext#refresh() 方法中:

1
2
3
4
5
6
7
8
9
10
11
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// --snip--

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

// --snip--
}
}

而在 prepareBeanFactory() 方法中有:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// --snip--

// 加载 ApplicationContextAwareProcessor
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略某些类型 Bean 的依赖注入
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

// --snip--
}

beanFactory.ignoreDependencyInterface() 方法用于指定自动装配(autowiring)时忽略的接口,注意 autowiring@Autowired 注解的区别。

ignoreDependencyInterface() 的设置与下面两种场景有关:

  • 基于 XML 进行配置时,<beans> 标签使用 default-autowire="byType" 属性;
  • 基于注解进行配置时,@Bean 注解使用 autowire = Autowire.BY_TYPE 属性,但这个属性在 Spring 5.1 中已被废弃。

当配置了通过类型(BY_TYPE)进行自动装配,在构造某个 Bean 时,如果这个 Bean 中的成员变量对应的类型在 Spring 容器中已存在,并且提供了对应的 Setter,那么此时会自动将对应的 Bean 注入到目标 Bean 中。

对这些 Aware 调用 ignoreDependencyInterface() 方法后,它们将不会被自动装配。

如今采用的都是注解配置,@Bean 注解中的 autowire 属性也被废弃,ignoreDependencyInterface() 方法的使用仅供了解,但不排除它正在某些不起眼的地方发挥着重要的作用呢?

拓展阅读:打开BeanFactory ignoreDependencyInterface方法的正确姿势

4. 两种方式的区别

4.1 触发时机不同

AbstractAutowireCapableBeanFactory#doCreateBean() 方法中,先执行 populateBean() 完成依赖注入,然后执行 initializeBean() 方法初始化 Bean:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
// --snip--
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 填充 Bean:进行依赖注入
populateBean(beanName, mbd, instanceWrapper);
// 初始化 Bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException bce && beanName.equals(bce.getBeanName())) {
throw bce;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, ex.getMessage(), ex);
}
}
// --snip--
}

@Autowired 注解生效在 populateBean() 方法中完成,那 initializeBean() 方法呢?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
invokeAwareMethods(beanName, bean);

Object wrappedBean = bean;
// 调用 BeanPostProcessor 的 postProcessBeforeInitialization() 方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
// 执行初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
}
// 调用 BeanPostProcessor 的 postProcessAfterInitialization() 方法
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

ApplicationContextAware 接口中的 setApplicationContext() 方法的执行与 ApplicationContextAwareProcessor 相关,在其重写的 postProcessBeforeInitialization() 方法中执行。

因此,@Autowired 注解获取 ApplicationContext 的方式要早于重写 ApplicationContextAware 接口的方式。

使用 @Autowired 注解获取 ApplicationContext 并不是完全等价重写 ApplicationContextAware 接口来获取,在某些情况下,使用 @Autowired 注解无法获取到 ApplicationContext,而是只能通过重写 ApplicationContextAware 接口完成,具体内容参考 SpringBoot 常用拓展点 一文中对 ApplicationContextAware 的补充。

4.2 自定义程度不同

使用 @Autowired 注解就只能注入“干巴巴”的 ApplicationContext,而实现 ApplicationContextAware 接口可以进行更多的自定义逻辑。