封面来源:碧蓝航线 逆转彩虹之塔 活动CG
本文基于 SpringBoot 3.1.x
1. 如何获取
一般来说,获取 ApplicationContext 有两种方式:
实现 ApplicationContextAware 接口,Spring 会在合适的时机回调 setApplicationContext() 方法,获取到 ApplicationContext 实例;
使用 @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)时,会同时在 beanDefinitionNames 和 resolvableDependencies 搜索,因此能够注入 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 参数。
再比如后面的三行表示注入 ResourceLoader、ApplicationEventPublisher 和 ApplicationContext 时,注入的对象是 this,即:ApplicationContext。
简单来说:通过 @Autowired 注解注入 BeanFactory、ResourceLoader、ApplicationEventPublisher 和 ApplicationContext。
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;
注册 AutowiredAnnotationBeanPostProcessor 的 BeanDefinition
在执行 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() 方法时,将 AutowiredAnnotationBeanPostProcessor 的 BeanDefinition 注册到容器中:
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--
}
AutowiredAnnotationBeanPostProcessor 的 postProcessProperties() 方法中,先获取到 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 对象被整合到 InjectionMetadata 的 injectedElements 字段中。
完成 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 类型,也就是会执行到 AutowiredFieldElement 的 inject() 方法:
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() 方法,在该方法中调用 BeanFactory 的 resolveDependency() 方法来获取依赖注入的值:
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 注解进行依赖注入时可以在 beanDefinitionNames 和 resolvableDependencies 搜索要被注入的值。
3. ApplicationContextAware 接口
3.1 接口介绍
ApplicationContextAware 接口是 Aware 接口的子接口,Aware 接口是一个标记接口,类似于 Serializable 接口。实现了 Aware 接口的 Bean 能够通过一个回调方法被 Spring 容器通知(这个“通知”通常用来设置一些 Spring 相关的信息,因此回调方法通常以 set 开头,具体内容由各子接口确定),比如 EnvironmentAware、ApplicationEventPublisherAware 等接口,以及这里的 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 接口可以进行更多的自定义逻辑。