在Bean实例化过程中,会分别遍历BeanPostProcessor执行其postProcessBeforeInitialization和postProcessAfterInitialization方法。
AbstractAutowireCapableBeanFactory的initializeBean方法如下所示。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // BeanNameAware BeanClassLoaderAware BeanFactoryAware invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; // Synthetic默认为false if (mbd == null || !mbd.isSynthetic()) { // 执行前置处理 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 执行初始化方法或者((InitializingBean) bean).afterPropertiesSet(); invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // 执行后置处理 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
那么BeanPostProcessor有哪些?分别又起了什么作用呢?我们下面看一下。
0 = {ApplicationContextAwareProcessor@3701} 1 = {WebApplicationContextServletContextAwareProcessor@7061} 2 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@7062} 3 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@7063} 4 = {ConfigurationPropertiesBindingPostProcessor@7064} 5 = {AnnotationAwareAspectJAutoProxyCreator@5252} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" 6 = {DataSourceInitializerPostProcessor@7065} 7 = {MethodValidationPostProcessor@7066} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" 8 = {PersistenceExceptionTranslationPostProcessor@7067} "proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false" 9 = {WebServerFactoryCustomizerBeanPostProcessor@7068} 10 = {ErrorPageRegistrarBeanPostProcessor@7069} 11 = {ProjectingArgumentResolverRegistrar$ProjectingArgumentResolverBeanPostProcessor@7070} 12 = {WebMvcObjectMapperConfigurer@7071} 13 = {CommonAnnotationBeanPostProcessor@7014} 14 = {AutowiredAnnotationBeanPostProcessor@6935} 15 = {ApplicationListenerDetector@7072}
ApplicationListenerDetector | 返回bean | 如果当前bean是ApplicationListener且是单例的,尝试注册到applicationContext中 |
(1) ApplicationContextAwareProcessor
该后置处理器只有postProcessBeforeInitialization方法,主要是为EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware及ApplicationContextAware设置信息。
class ApplicationContextAwareProcessor implements BeanPostProcessor { private final ConfigurableApplicationContext applicationContext; private final StringValueResolver embeddedValueResolver; /** * Create a new ApplicationContextAwareProcessor for the given context. */ public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) { this.applicationContext = applicationContext; this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory()); } @Override @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)){ return bean; } AccessControlContext acc = null; if (System.getSecurityManager() != null) { acc = this.applicationContext.getBeanFactory().getAccessControlContext(); } // 获取到acc ,调用invokeAwareInterfaces、 if (acc != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareInterfaces(bean); return null; }, acc); } else { invokeAwareInterfaces(bean); } return bean; } // 判断是哪种类型,然后分别设置对应信息 private void invokeAwareInterfaces(Object bean) { if (bean instanceof EnvironmentAware) { ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment()); } if (bean instanceof EmbeddedValueResolverAware) { ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver); } if (bean instanceof ResourceLoaderAware) { ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext); } if (bean instanceof ApplicationEventPublisherAware) { ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext); } if (bean instanceof MessageSourceAware) { ((MessageSourceAware) bean).setMessageSource(this.applicationContext); } if (bean instanceof ApplicationContextAware) { ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext); } } }
before方法则是BeanPostProcessor默认实现的直接返回bean。
(2) WebApplicationContextServletContextAwareProcessor
其是ServletContextAwareProcessor一个变异,可以在初始化ServletContext或ServletConfig之前注册处理器时使用。内部维护了一个ConfigurableWebApplicationContext,用来获取ServletContext或ServletConfig。
其自身没有postProcessBeforeInitialization或者方法,继承自父类ServletContextAwareProcessor实现了BeanPostProcessor接口。其after方法直接返回了bean。ServletContextAwareProcessor的Bean后置处理如下所示
// 设置ServletContext 和 ServletConfig @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (getServletContext() != null && bean instanceof ServletContextAware) { ((ServletContextAware) bean).setServletContext(getServletContext()); } if (getServletConfig() != null && bean instanceof ServletConfigAware) { ((ServletConfigAware) bean).setServletConfig(getServletConfig()); } return bean; } // 直接返回bean @Override public Object postProcessAfterInitialization(Object bean, String beanName) { return bean; }
(3) ImportAwareBeanPostProcessor
也就是说ConfigurationClassPostProcessor
的内部类ImportAwareBeanPostProcessor
。
private static class ImportAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { private final BeanFactory beanFactory; public ImportAwareBeanPostProcessor(BeanFactory beanFactory) { this.beanFactory = beanFactory; } @Override public PropertyValues postProcessProperties(@Nullable PropertyValues pvs, Object bean, String beanName) { // Inject the BeanFactory before AutowiredAnnotationBeanPostProcessor's // postProcessProperties method attempts to autowire other configuration beans. if (bean instanceof EnhancedConfiguration) { ((EnhancedConfiguration) bean).setBeanFactory(this.beanFactory); } return pvs; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { if (bean instanceof ImportAware) { ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class); AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName()); if (importingClass != null) { ((ImportAware) bean).setImportMetadata(importingClass); } } return bean; } }
其父类InstantiationAwareBeanPostProcessorAdapter
关于Bean的后置处理before/after方法如下所示。
// 直接返回 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } // 直接返回 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
那么ImportAwareBeanPostProcessor 重写的postProcessBeforeInitialization是个什么作用呢?我们看下图,为当前bean(ProxyTransactionManagementConfiguration)找到com.recommend.config.mybatis.MybatisPlusConfig。
在执行setImportMetadata方法时为其设置配置类MybatisPlusConfig上面的注解元信息。
(ProxyTransactionManagementConfiguration 继承自AbstractTransactionManagementConfiguration,父类实现了setImportMetadata方法)。
(4) BeanPostProcessorChecker
BeanPostProcessorChecker 是 PostProcessorRegistrationDelegate的内部类。其before方法直接返回了bean,after方法只是打印了一个log info。
private static final class BeanPostProcessorChecker implements BeanPostProcessor { private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class); private final ConfigurableListableBeanFactory beanFactory; private final int beanPostProcessorTargetCount; public BeanPostProcessorChecker(ConfigurableListableBeanFactory beanFactory, int beanPostProcessorTargetCount) { this.beanFactory = beanFactory; this.beanPostProcessorTargetCount = beanPostProcessorTargetCount; } // 直接返回 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } // 如方法所示,只是打印了一个log info @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) && this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) { if (logger.isInfoEnabled()) { logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() + "] is not eligible for getting processed by all BeanPostProcessors " + "(for example: not eligible for auto-proxying)"); } } return bean; } private boolean isInfrastructureBean(@Nullable String beanName) { if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) { BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName); return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE); } return false; } }
(5) ConfigurationPropertiesBindingPostProcessor
该处理器的作用从名字上也可以直接看出来,将标注了@ConfigurationProperties注解的bean与PropertySources绑定起来。PropertySources是什么呢?
在SpringBoot中yml与properties配置文件及bean取值赋值一文中我们讲过@ConfigurationProperties注解告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定。PropertySources就是我们在各个配置文件中的属性-值配置。如下所示其只覆盖了postProcessBeforeInitialization
方法,将bean与PropertySources进行了绑定。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName)); return bean; }
(6) AnnotationAwareAspectJAutoProxyCreator
这个类或者说这个类家族是我们值得关注的,其在Spring AOP的执行流程中起到了不可磨灭的作用。
该类自身并没有重写before or after方法,但是其祖父类AbstractAutoProxyCreator对其进行了实现。
// 直接返回 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } // 使用配置的拦截器(advice)创建一个代理 @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
这个方法是spring aop的核心。在Bean实例化过程中如果应用配置了切面,且切面的advice拦截了该bean的某个方法那么wrapIfNecessary方法就会使用切面的advice为该bean创建一个代理。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } // 是否需要代理 不需要直接返回 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. 这一步很重要 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { // 说明需要代理 this.advisedBeans.put(cacheKey, Boolean.TRUE); Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); // 放入代理缓存 this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } // 放入advisedBeans 也就是说当前bean是否为一个advisor this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
那么如何创建代理呢?这里我们不展开分析,简单描述是Spring会拿到一个代理工厂(默认是DefaultAopProxyFactory)然后使用策略模式创建ObjenesisCglibAopProxy
或者JdkDynamicAopProxy
。
(7) DataSourceInitializerPostProcessor
该后置处理器的作用十分简明,当DataSource bean创建后触发该方法,会立即创建DataSourceInitializerInvoker。其before方法直接返回了bean,after方法实现了DataSourceInitializerInvoker实例化功能。
class DataSourceInitializerPostProcessor implements BeanPostProcessor, Ordered { @Override public int getOrder() { return Ordered.HIGHEST_PRECEDENCE + 1; } @Autowired private BeanFactory beanFactory; @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof DataSource) { // force initialization of this bean as soon as we see a DataSource this.beanFactory.getBean(DataSourceInitializerInvoker.class); } return bean; } }
(8) MethodValidationPostProcessor
该类自身并没有重写before or after方法,其祖父类AbstractAdvisingBeanPostProcessor重写了这两个方法。
PersistenceExceptionTranslationPostProcessor
和MethodValidationPostProcessor
一样,也是继承自AbstractAdvisingBeanPostProcessor
。
//直接返回 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } // Add our local Advisor to the existing proxy's Advisor chain... // 如果当前advised没有被冷冻(默认就是false)且当前将advisor适合bean // 则将advisor加入到已经存在的代理的Advisor链 @Override public Object postProcessAfterInitialization(Object bean, String beanName) { if (this.advisor == null || bean instanceof AopInfrastructureBean) { // Ignore AOP infrastructure such as scoped proxies. return bean; } if (bean instanceof Advised) { Advised advised = (Advised) bean; if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) { // Add our local Advisor to the existing proxy's Advisor chain... if (this.beforeExistingAdvisors) { advised.addAdvisor(0, this.advisor); } else { advised.addAdvisor(this.advisor); } return bean; } } if (isEligible(bean, beanName)) { ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName); if (!proxyFactory.isProxyTargetClass()) { evaluateProxyInterfaces(bean.getClass(), proxyFactory); } proxyFactory.addAdvisor(this.advisor); customizeProxyFactory(proxyFactory); return proxyFactory.getProxy(getProxyClassLoader()); } // No proxy needed. return bean; }
(9) WebServerFactoryCustomizerBeanPostProcessor
WebServerFactoryCustomizer是一个策略接口,其方法void customize(T factory);用来自定义WebServerFactory。WebServerFactoryCustomizerBeanPostProcessor就是针对所有WebServerFactory应用的。
如果当前bean是webServerFactory,则寻找WebServerFactoryCustomizer并反射调用customize方法。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof WebServerFactory) { postProcessBeforeInitialization((WebServerFactory) bean); } return bean; } // 调用所有WebServerFactoryCustomizer的customize方法 @SuppressWarnings("unchecked") private void postProcessBeforeInitialization(WebServerFactory webServerFactory) { LambdaSafe.callbacks(WebServerFactoryCustomizer.class, getCustomizers(), webServerFactory) .withLogger(WebServerFactoryCustomizerBeanPostProcessor.class) .invoke((customizer) -> customizer.customize(webServerFactory)); } // 直接返回 @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
如下图所示,这里会循环调用这些XXXCustomizer的customize方法。
0 = {TomcatWebSocketServletWebServerCustomizer@5428} 1 = {ServletWebServerFactoryCustomizer@5429} 2 = {TomcatServletWebServerFactoryCustomizer@5430} 3 = {TomcatWebServerFactoryCustomizer@5431} 4 = {HttpEncodingAutoConfiguration$LocaleCharsetMappingsCustomizer@5432}
(10) ErrorPageRegistrarBeanPostProcessor
如下代码所示,其postProcessBeforeInitialization方法将会扫描得到所有的ErrorPageRegistrar 然后调用其registerErrorPages方法进行注册。即为ErrorPageRegistry注册错误页面配置。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof ErrorPageRegistry) { postProcessBeforeInitialization((ErrorPageRegistry) bean); } return bean; } // 直接返回Bean @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; } private void postProcessBeforeInitialization(ErrorPageRegistry registry) { for (ErrorPageRegistrar registrar : getRegistrars()) { registrar.registerErrorPages(registry); } }
错误页面配置如下所示,我们自定义ErrorPageConfig 实现了ErrorPageRegistrar 重写了registerErrorPages方法。
@Component public class ErrorPageConfig implements ErrorPageRegistrar { @Override public void registerErrorPages(ErrorPageRegistry registry) { ErrorPage error400Page = new ErrorPage(HttpStatus.BAD_REQUEST, "/error/404"); ErrorPage error404Page = new ErrorPage(HttpStatus.NOT_FOUND, "/error/404"); ErrorPage error500Page = new ErrorPage(HttpStatus.INTERNAL_SERVER_ERROR, "/error/500"); registry.addErrorPages(error400Page,error404Page,error500Page); } }
(11) ProjectingArgumentResolverBeanPostProcessor
其是ProjectingArgumentResolverRegistrar的内部类,主要用来修改RequestMappingHandlerAdapter。其将会添加ProxyingHandlerMethodArgumentResolver作为RequestMappingHandlerAdapter的第一个HandlerMethodArgumentResolver
@Nullable @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } /* * (non-Javadoc) * @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization(java.lang.Object, java.lang.String) */ @Nullable @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (!RequestMappingHandlerAdapter.class.isInstance(bean)) { return bean; } RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean; List<HandlerMethodArgumentResolver> currentResolvers = adapter.getArgumentResolvers(); if (currentResolvers == null) { throw new IllegalStateException( String.format("No HandlerMethodArgumentResolvers found in RequestMappingHandlerAdapter %s!", beanName)); } List<HandlerMethodArgumentResolver> newResolvers = new ArrayList<HandlerMethodArgumentResolver>( currentResolvers.size() + 1); newResolvers.add(resolver); newResolvers.addAll(currentResolvers); adapter.setArgumentResolvers(newResolvers); return adapter; }
ProxyingHandlerMethodArgumentResolver
继承树示意图如下所示
(12) WebMvcObjectMapperConfigurer
其postProcessAfterInitialization毫无作用直接返回当前Bean。postProcessBeforeInitialization对RequestMappingHandlerAdapter进行了配置。如果bean是RequestMappingHandlerAdapter,则为其设置MessageConverters。
@Override public Object postProcessBeforeInitialization( Object bean, String beanName) throws BeansException { if (bean instanceof RequestMappingHandlerAdapter) { RequestMappingHandlerAdapter adapter = (RequestMappingHandlerAdapter) bean; adapter.setMessageConverters(configureMessageConverters(adapter.getMessageConverters())); } return bean; } private List<HttpMessageConverter<?>> configureMessageConverters( List<HttpMessageConverter<?>> converters) { // 获取到converters里面的MappingJackson2HttpMessageConverter进行遍历 Iterable<MappingJackson2HttpMessageConverter> jackson2Converters = jackson2Converters(converters); if (StreamSupport.stream(jackson2Converters.spliterator(), false).count() > 0) { for (MappingJackson2HttpMessageConverter each : jackson2Converters) { fireObjectMapperConfiguredEvent(each.getObjectMapper()); } } else { // 配置MappingJackson2HttpMessageConverter 并发布事件 converters.add(configuredMessageConverter()); } return new ArrayList<>(converters); } // 直接返回bean @Override public Object postProcessAfterInitialization( Object bean, String beanName) throws BeansException { return bean; }
这里我们继续看一下其fireObjectMapperConfiguredEvent(each.getObjectMapper());做了什么。
如下代码所示,其调用事件发布器发布了一个事件new ObjectMapperConfigured(this, objectMapper)。
private void fireObjectMapperConfiguredEvent(ObjectMapper objectMapper) { applicationEventPublisher.publishEvent(new ObjectMapperConfigured(this, objectMapper)); }
configuredMessageConverter方法
private MappingJackson2HttpMessageConverter configuredMessageConverter() { // 新建一个MappingJackson2HttpMessageConverter MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter(); ObjectMapper objectMapper = new ObjectMapper(); // 为messageConverter设置objectMapper messageConverter.setObjectMapper(objectMapper); // 发布事件 fireObjectMapperConfiguredEvent(objectMapper); return messageConverter; }
(13) CommonAnnotationBeanPostProcessor
其before方法这里会反射调用bean的初始化方法,比如我们加了注解的 @PostConstruct
方法。而after方法则直接返回bean。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass()); try { metadata.invokeInitMethods(bean, beanName); } catch (InvocationTargetException ex) { throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Failed to invoke init method", ex); } return bean; } //直接返回bean @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
如下图所示在实例化HomeController
时会反射调用我们加了注解的@PostConstruct
方法。
关于CommonAnnotationBeanPostProcessor我们需要多了解一下。在一起技术体系中,该后置处理器是被context:annotation-config或者context:component-scan自动注入的。其对JSR-250中常见注解提供了支持,比如@PostConstruct、@PreDestroy以及@Resource。
如下所示其继承自InitDestroyAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor接口。
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor implements InstantiationAwareBeanPostProcessor, BeanFactoryAware, Serializable { }
关于PreDestroy和PostConstruct注解的实现,InitDestroyAnnotationBeanPostProcessor在postProcessBeforeInitialization对PostConstruct进行了支持,在postProcessBeforeDestruction对@PostConstruct进行了支持。
(14) AutowiredAnnotationBeanPostProcessor
其继承自InstantiationAwareBeanPostProcessorAdapter
,而该类并未有任何额外动作,只是直接返回bean。
@Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { return bean; }
(15) ApplicationListenerDetector
其before方法直接返回bean,其postProcessAfterInitialization方法会判断当前bean是否为ApplicationListener,如果是该类型且是单例则将当前bean注册到applicationContext中。 //
其addApplicationListener如下所示,一方面放到private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();中,一方面放到AbstractApplicationEventMulticaster的内部类ListenerRetriever的public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();中。
@Override public void addApplicationListener(ApplicationListener<?> listener) { Assert.notNull(listener, "ApplicationListener must not be null"); if (this.applicationEventMulticaster != null) { this.applicationEventMulticaster.addApplicationListener(listener); } this.applicationListeners.add(listener); }