封面来源:碧蓝航线 逆转彩虹之塔 活动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 private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap <>(256 );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) { prepareBeanFactory(beanFactory); } }
而在 prepareBeanFactory()
方法中有:
1 2 3 4 5 6 7 8 9 10 11 12 protected void prepareBeanFactory (ConfigurableListableBeanFactory beanFactory) { beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this ); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this ); beanFactory.registerResolvableDependency(ApplicationContext.class, this ); }
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) { 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)); } }
从这段代码还能知道 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) { try { 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) { try { finishBeanFactoryInitialization(beanFactory); } } }
在 finishBeanFactoryInitialization()
方法中又调用了 preInstantiateSingletons()
方法:
1 2 3 4 5 6 protected void finishBeanFactoryInitialization (ConfigurableListableBeanFactory beanFactory) { 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 ); } List<String> beanNames = new ArrayList <>(this .beanDefinitionNames); for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { if (isFactoryBean(beanName)) { Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) { getBean(beanName); } } else { getBean(beanName); } } } 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 { if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } }
创建 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 { try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'" ); } return beanInstance; } }
在 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 { Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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); } } }
在 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) { 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; } } }
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) { 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); 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) { } 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) { } }
那注入的数据又是怎么来的呢?
回到 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()) { 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) { 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) { Object value; try { value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter); } }
接下来会进入 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()); if (Optional.class == descriptor.getDependencyType()) { return createOptionalDependency(descriptor, requestingBeanName); } else if (ObjectFactory.class == descriptor.getDependencyType() || ObjectProvider.class == descriptor.getDependencyType()) { return new DependencyObjectProvider (descriptor, requestingBeanName); } 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); for (Map.Entry<Class<?>, Object> classObjectEntry : this .resolvableDependencies.entrySet()) { } for (String candidate : candidateNames) { if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) { addCandidateEntry(result, candidate, descriptor, requiredType); } } }
至此证明 @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) { 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) { prepareBeanFactory(beanFactory); } }
而在 prepareBeanFactory()
方法中有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected void prepareBeanFactory (ConfigurableListableBeanFactory beanFactory) { beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor (this )); 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); }
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 { Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); 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); } } }
@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; 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); } 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
接口可以进行更多的自定义逻辑。