当前位置: 首页 > news >正文

Spring IOC源码篇八 核心方法prepareBeanFactory

AbstractApplicationContext.prepareBeanFactory

    • 1.写在前面
    • 2.AbstractApplicationContext.prepareBeanFactory方法
    • 3.beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    • 4.beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    • 5.Aware接口
      • Aware接口作用
      • 常见的Aware接口
      • Aware接口@Autowired的区别
      • 源码分析
        • ApplicationContextAwareProcessor.invokeAwareInterfaces方法
        • AbstractAutowireCapableBeanFactory.ignoreDependencyInterface(Class<?> ifc)方法
    • 6.registerResolvableDependency方法
      • DefaultListableBeanFactory.registerResolvableDependency方法
    • 7.ApplicationListenerDetector

1.写在前面

本文介绍prepareBeanFactory方法,对 BeanFactory 进行预处理,涉及到核心的对象初始化的地方会大概介绍它使用的地方及场景,会涉及到后续的源码。这里大家先混个熟悉。后续可以在回头看

2.AbstractApplicationContext.prepareBeanFactory方法

核心逻辑:
对 BeanFactory 进行预处理,使其具备处理 Spring 上下文特有功能的能力
1.配置类加载器、表达式解析器等基础组件;
2.注册感知接口(如 ApplicationContextAware)的处理逻辑;
3.绑定容器核心组件(如 ResourceLoader、ApplicationEventPublisher)为可注入依赖;
4.注册默认环境 Bean(如 Environment、系统属性等)。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {// 设置类加载器beanFactory.setBeanClassLoader(getClassLoader());if (!shouldIgnoreSpel) {// 注册Spring表达式语言(SpEL)解析器,支持Bean定义中使用#{...}表达式beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));}// 注册资源编辑器 registrar,支持将字符串转换为Resource等类型(如解析"classpath:xxx")beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));// 添加ApplicationContextAwareProcessor,处理实现了Aware接口的Bean(如注入ApplicationContext)beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));// 忽略特定Aware接口的自动注入:这些接口由ApplicationContextAwareProcessor处理,而非BeanFactory的依赖注入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时,使用当前BeanFactorybeanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);// 注入ResourceLoader时,使用当前ApplicationContext(它实现了ResourceLoader)beanFactory.registerResolvableDependency(ResourceLoader.class, this);// 注入事件发布器时,使用当前ApplicationContextbeanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);// 注入ApplicationContext时,使用当前上下文实例beanFactory.registerResolvableDependency(ApplicationContext.class, this);// 添加早期后置处理器:检测内部Bean是否为ApplicationListenerbeanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));// 若存在 LoadTimeWeaver Bean,配置类加载时织入(用于 AspectJ 等 AOP 织入)if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {// 添加LoadTimeWeaverAwareProcessor,处理实现LoadTimeWeaverAware接口的BeanbeanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));// 设置临时类加载器,用于类型匹配(织入时可能需要修改类字节码)beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));}// 注册默认环境Bean(单例)if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {// 注册Environment实例beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());}if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {// 注册系统属性beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());}if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {// 注册系统环境变量beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());}if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {// 注册应用启动监控器beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());}
}

3.beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));

SpEL表达式详解
StandardBeanExpressionResolver构造器

public StandardBeanExpressionResolver(@Nullable ClassLoader beanClassLoader) {// 创建了一个SpEL表达式解析器this.expressionParser = new SpelExpressionParser(new SpelParserConfiguration(null, beanClassLoader));
}

StandardBeanExpressionResolver被使用的地方:
1.AbstractApplicationContext.refresh()方法的
finishBeanFactoryInitialization(beanFactory);
2.AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)方法的
beanFactory.preInstantiateSingletons()
3.DefaultListableBeanFactory.preInstantiateSingletons()方法的
getBean(beanName)
4.AbstractBeanFactory.getBean(String name)方法的
doGetBean(name, null, null, false)
5.AbstractBeanFactory.doGetBean(String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)方法的
createBean(beanName, mbd, args)
6.AbstractAutowireCapableBeanFactory.createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法的
Object beanInstance = doCreateBean(beanName, mbdToUse, args)
7.AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法的
populateBean(beanName, mbd, instanceWrapper)
8.AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法的
applyPropertyValues(beanName, mbd, bw, pvs)
9.AbstractAutowireCapableBeanFactory.applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)方法的
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue)
10.BeanDefinitionValueResolver.resolveValueIfNecessary(Object argName, @Nullable Object value)方法的
Object valueObject = evaluate(typedStringValue)
11.BeanDefinitionValueResolver.evaluate(TypedStringValue value)方法的
Object result = doEvaluate(value.getValue())
12.BeanDefinitionValueResolver.doEvaluate(@Nullable String value)方法的
return this.beanFactory.evaluateBeanDefinitionString(value, this.beanDefinition)
13.AbstractBeanFactory.evaluateBeanDefinitionString(@Nullable String value, @Nullable BeanDefinition beanDefinition)方法的
return this.beanExpressionResolver.evaluate(value, new BeanExpressionContext(this, scope))
此时的beanExpressionResolver就是StandardBeanExpressionResolver
14.StandardBeanExpressionResolver.evaluate(@Nullable String value, return expr.getValue(sec)
此时的expressionParser就是SpelExpressionParser

4.beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

AbstractBeanFactory.addPropertyEditorRegistrar方法

private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);/*** 添加属性编辑注册器*/
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {Assert.notNull(registrar, "PropertyEditorRegistrar must not be null");this.propertyEditorRegistrars.add(registrar);
}

ResourceEditorRegistrar

/*** 构造器方法*/
public ResourceEditorRegistrar(ResourceLoader resourceLoader, PropertyResolver propertyResolver) {this.resourceLoader = resourceLoader;this.propertyResolver = propertyResolver;
}/*** ResourceEditorRegistrar.registerCustomEditors方法* 注册一系列与资源处理相关的 PropertyEditor,确保 Spring 容器在解析 XML 配置、注解属性(如 @Value)中的* 资源路径字符串时,能自动转换为对应的 Java 资源对象(如 Resource、File、URL 等)*/
public void registerCustomEditors(PropertyEditorRegistry registry) {// 创建基础资源编辑器(处理 Resource 类型的核心编辑器)ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);// 注册 Resource 及其子接口的编辑器(核心资源类型)doRegisterEditor(registry, Resource.class, baseEditor);doRegisterEditor(registry, ContextResource.class, baseEditor);doRegisterEditor(registry, WritableResource.class, baseEditor);// 注册基于 Resource 的派生类型编辑器(输入流、文件等)doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));doRegisterEditor(registry, File.class, new FileEditor(baseEditor));doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));// 注册类加载相关的编辑器(依赖类加载器)ClassLoader classLoader = this.resourceLoader.getClassLoader();doRegisterEditor(registry, URI.class, new URIEditor(classLoader));doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));// 若支持资源模式解析(如通配符),注册 Resource 数组编辑器if (this.resourceLoader instanceof ResourcePatternResolver) {doRegisterEditor(registry, Resource[].class,new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));}
}

以Resource为例:

测试类:

public class Main {/**** @param args*/public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("application-beans.xml");Test test = context.getBean(Test.class);System.out.println(test.getResource());}
}

实体类:
新增Resource属性
private Resource resource;

public class Test {private String username;private String password;private List<String> aliases;private Resource resource;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public List<String> getAliases() {return aliases;}public void setAliases(List<String> aliases) {this.aliases = aliases;}public Resource getResource() {return resource;}public void setResource(Resource resource) {this.resource = resource;}
}

配置文件:application-beans.xml

<?xml version="1.0" encoding="UTF-8" ?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:model="http://www.yuriy.com/schema/tag"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.yuriy.com/schema/taghttp://www.yuriy.com/schema/tag/user.xsd"><model:user id="1" username="root" phone="123456" address="四川省成都市龙泉驿区大面镇"/><context:property-placeholder location="classpath:database.properties"/><bean id="test" class="com.arco.spring.code.Test"><property name="username" value="#{user.getUsername()}"/><property name="password" value="${jdbc.password}"/><property name="aliases"><list><value>yuriy1</value><value>yuriy2</value><value>yuriy3</value></list></property><property name="resource" value="classpath:application.properties"/></bean><bean id="user" class="com.arco.spring.code.tag.User"><property name="username" value="wangpeng"/></bean><alias name="test" alias="yuriy-test"/>
</beans>

流程从第二步中1-8均相同
9.AbstractAutowireCapableBeanFactory.applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs)方法的
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter)
10.AbstractAutowireCapableBeanFactory.convertForProperty(
@Nullable Object value, String propertyName, BeanWrapper bw, TypeConverter converter)方法的
return ((BeanWrapperImpl) converter).convertForProperty(value, propertyName)
11.BeanWrapperImpl.convertForProperty(@Nullable Object value, String propertyName)方法的
return convertForProperty(propertyName, null, value, td)
12.跳过一些重构方法来到TypeConverterDelegate.convertIfNecessary(@Nullable String propertyName, @Nullable Object oldValue, @Nullable Object newValue,
@Nullable Class requiredType, @Nullable TypeDescriptor typeDescriptor)方法的
findDefaultEditor(requiredType)
13.TypeConverterDelegate.findDefaultEditor(@Nullable Class<?> requiredType)方法的 editor = this.propertyEditorRegistry.getDefaultEditor(requiredType) 14.PropertyEditorRegistrySupport.getCustomEditor(@Nullable Class<?> requiredType)方法的
PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType)返回
debug图片:
这里就是ResourceEditorRegistrar.registerCustomEditors注入的
在这里插入图片描述
15.TypeConverterDelegate.doConvertTextValue(@Nullable Object oldValue, String newTextValue, PropertyEditor editor)方法的editor.setAsText(newTextValue)
16.最终来的ResourceEditor.setAsText(String text)方法ResourceEditor继承PropertyEditorSupport

/**** 将classpath:application.properties字符串解析成Resource并赋值*/
public void setAsText(String text) {if (StringUtils.hasText(text)) {String locationToUse = resolvePath(text).trim();setValue(this.resourceLoader.getResource(locationToUse));}else {setValue(null);}
}

熟悉了以上流程我们可以自定义一个属性编辑器实现我们自己的功能,这里也是spring的一个扩展点

5.Aware接口

Aware接口作用

Spring 中的 Aware 接口是一组标记式接口,用于让 Bean 感知并主动获取 Spring 容器的核心组件(如 ApplicationContext、BeanFactory、ResourceLoader 等)。通过实现特定的 Aware 接口,Bean 可以在生命周期中与 Spring 容器深度交互,获取容器级别的资源或信息。
Aware 接口的核心价值是打破 “被动依赖注入” 的限制,允许 Bean 主动向容器 “索取” 资源,而非仅通过 @Autowired 等注解被动接收依赖。这种机制让 Bean 能更灵活地与 Spring 容器集成,适用于框架扩展、容器级操作(如发布事件、读取环境配置)等场景。

常见的Aware接口

ApplicationContextAware
BeanFactoryAware
ResourceLoaderAware
EnvironmentAware
BeanNameAware
ApplicationEventPublisherAware
MessageSourceAware

Aware接口@Autowired的区别

@Autowired:
适用于大多数场景,通过依赖注入自动获取组件(如 @Autowired ApplicationContext ctx),代码耦合度低,符合 “依赖倒置” 原则。
Aware 接口:
适用于框架级代码或需要在初始化早期获取容器组件的场景(如 BeanFactoryAware 可在 @PostConstruct 之前获取容器),但会增加代码与 Spring 框架的耦合。

源码分析

// 添加ApplicationContextAwareProcessor,处理实现了Aware接口的Bean(如注入ApplicationContext)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 忽略特定Aware接口的自动注入:这些接口由ApplicationContextAwareProcessor处理,而非BeanFactory的依赖注入
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);
ApplicationContextAwareProcessor.invokeAwareInterfaces方法

ApplicationContextAwareProcessor实现了BeanPostProcessor接口
在bean初始化前调用postProcessBeforeInitialization方法手动为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 ApplicationStartupAware) {((ApplicationStartupAware) bean).setApplicationStartup(this.applicationContext.getApplicationStartup());}if (bean instanceof ApplicationContextAware) {((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);}
}

另外三个Aware接口
BeanNameAware
BeanClassLoaderAware
BeanFactoryAware
以上三个Aware接口处理方式和上面的处理不同
流程从第二步中1-6均相同
7.AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法的
exposedObject = initializeBean(beanName, exposedObject, mbd);
8.AbstractAutowireCapableBeanFactory.initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd)方法的
invokeAwareMethods(beanName, bean)

private void invokeAwareMethods(String beanName, Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {ClassLoader bcl = getBeanClassLoader();if (bcl != null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}

以上三个接口在哪里被忽略:
1.AbstractApplicationContext.refresh方法的
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
2.AbstractApplicationContext.refreshBeanFactory方法的
refreshBeanFactory()
3.AbstractRefreshableApplicationContext.refreshBeanFactory()方法的
DefaultListableBeanFactory beanFactory = createBeanFactory()
4.AbstractRefreshableApplicationContextcreateBeanFactory()方法的
return new DefaultListableBeanFactory(getInternalParentBeanFactory())
5.在DefaultListableBeanFactory父类AbstractAutowireCapableBeanFactory无参构造器

public AbstractAutowireCapableBeanFactory() {super();ignoreDependencyInterface(BeanNameAware.class);ignoreDependencyInterface(BeanFactoryAware.class);ignoreDependencyInterface(BeanClassLoaderAware.class);if (NativeDetector.inNativeImage()) {this.instantiationStrategy = new SimpleInstantiationStrategy();}else {this.instantiationStrategy = new CglibSubclassingInstantiationStrategy();}
}
AbstractAutowireCapableBeanFactory.ignoreDependencyInterface(Class<?> ifc)方法
public void ignoreDependencyInterface(Class<?> ifc) {// 将类添加至ignoredDependencyInterfaces集合中this.ignoredDependencyInterfaces.add(ifc);
}

ignoredDependencyInterfaces属性在哪里被使用:
AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法。以下是方法的部分代码。在方法filterPropertyDescriptorsForDependencyCheck中ignoredDependencyInterfaces属性会被使用到。但由于 postProcessProperties 方法的默认实现不会返回 null,导致 filterPropertyDescriptorsForDependencyCheck 很少被触发。
1.优先调用 postProcessProperties(Spring 5.1+ 新增,替代旧的 postProcessPropertyValues)
2.若 postProcessProperties 返回 null,则降级调用 postProcessPropertyValues,此时需要先调用 filterPropertyDescriptorsForDependencyCheck 获取过滤后的属性描述符。在 Spring 内置的 InstantiationAwareBeanPostProcessor 实现中(如 AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor),postProcessProperties 方法默认不会返回 null,而是返回处理后的 PropertyValues 或原对象,因此 filterPropertyDescriptorsForDependencyCheck 几乎不会被执行。

if (hasInstAwareBpps) {if (pvs == null) {pvs = mbd.getPropertyValues();}for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {if (filteredPds == null) {filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);}pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);if (pvsToUse == null) {return;}}pvs = pvsToUse;}}

6.registerResolvableDependency方法

beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

DefaultListableBeanFactory.registerResolvableDependency方法

resolvableDependencies属性中添加对象。
作用:
当某个 Bean 的属性或构造函数参数类型为 BeanFactory、ApplicationContext 等时,Spring 会直接使用这里注册的 “可解析依赖” 进行注入,无需手动定义这些类型的 Bean。

public void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue) {Assert.notNull(dependencyType, "Dependency type must not be null");if (autowiredValue != null) {if (!(autowiredValue instanceof ObjectFactory || dependencyType.isInstance(autowiredValue))) {throw new IllegalArgumentException("Value [" + autowiredValue +"] does not implement specified dependency type [" + dependencyType.getName() + "]");}this.resolvableDependencies.put(dependencyType, autowiredValue);}
}

resolvableDependencies属性在哪里被使用:
列如当我们使用@Autowired注入属性时:
1.AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法的
PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
2.AutowiredAnnotationBeanPostProcessor.postProcessProperties(PropertyValues pvs, Object bean, String beanName)方法的
metadata.inject(bean, beanName, pvs)
3.一直到DefaultListableBeanFactory.findAutowireCandidates(
@Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor)方法

7.ApplicationListenerDetector

ApplicationListenerDetector 实现 BeanPostProcessor
ApplicationListenerDetector 是 Spring 框架中的一个 BeanPostProcessor 实现类,主要用于在 Spring 容器初始化过程中自动检测并注册实现了 ApplicationListener 接口的 Bean 作为事件监听器,确保这些监听器能接收并处理容器发布的事件(如 ContextRefreshedEvent、ContextClosedEvent 等)。

作用:
1.在 Bean 初始化后,检测该 Bean 是否实现了 ApplicationListener 接口;
2.若实现了该接口,将其注册到 Spring 容器的事件发布器(ApplicationEventPublisher)中;

public Object postProcessAfterInitialization(Object bean, String beanName) {// 判断当前 Bean 是否实现了 ApplicationListener 接口if (bean instanceof ApplicationListener) {// singletonNames 存储 Bean 名称与“是否为单例”的映射(TRUE:单例;FALSE:非单例)Boolean flag = this.singletonNames.get(beanName);// 若为单例 Bean(flag 为 TRUE)if (Boolean.TRUE.equals(flag)) {// 单例 Bean(顶级 Bean 或内部 Bean):直接注册为事件监听器this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);}// 若为非单例 Bean(flag 为 FALSE)else if (Boolean.FALSE.equals(flag)) {if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {// 警告:非单例的内部 Bean 无法可靠接收事件logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +"but is not reachable for event multicasting by its containing ApplicationContext " +"because it does not have singleton scope. Only top-level listener beans are allowed " +"to be of non-singleton scope.");}// 移除非单例 Bean 的标记,避免重复处理this.singletonNames.remove(beanName);}}return bean;
}
http://www.dtcms.com/a/524263.html

相关文章:

  • S10--循环队列
  • 基于月尺度水分平衡模型的葡萄园规划与行间管理决策
  • 网站的前期推广网页设计与制作源代码
  • PY32F040单片机介绍(3)
  • 白云网站 建设seo信科上海城市分站seo
  • Python流程控制语法结构-选择分支新特性
  • 快速学完 LeetCode top 1~50 [特殊字符]
  • 河南网站开发培训价格商丘哪里做网站比较好
  • 【常用设计模式全解析】创建型模式(聚焦对象创建机制)、结构型模式(优化类与对象的组合关系)、行为型模式(规范对象间的交互行为)
  • MFF-YOLOv8:基于多尺度特征融合的无人机遥感图像小目标检测
  • SSM框架-MyBatis1
  • 从一开始部署Android项目Sonarqube的自动化扫码+通知+增量扫描功能(Win环境、Docker,基于Jenkins)
  • 对我单位网站进行改版苏州网站建设开发公司
  • 网站架构文案软文推广去哪个平台好
  • 【Cuda C 编程指南第7章 硬件实现】
  • 低代码开发,如何让企业应用搭建化繁为简?
  • npm使用国内淘宝镜像的方法
  • pnpm + webpack + vue 项目依赖缺失错误排查与解决
  • 北斗GNSS变形监测一体机在地质灾害和桥梁安全中的应用解析
  • C++ 中的 initializer_list 详解
  • 网站建设与管理好处网站 流量 不够用
  • 2025年第六届MathorCup大数据竞赛赛题浅析-助攻快速选题
  • 网站注册转化率网站建设营销
  • 做食品网站的素材海南省建设注册执业资格中心网站
  • 烧结工序的“隐形守护者”:在线监测如何成为钢铁制造的关键支柱
  • Vue2下项目集成DeepSeek API
  • Mysql作业3
  • 指定列交集内容合并-Rscript_v1.0
  • 基于单片机的牧场奶牛养殖系统设计(论文+源码)
  • 市场上有哪些主流的 MFT 管理软件?