parent
451c575e23
commit
63686a77e5
|
@ -127,11 +127,11 @@
|
||||||
|
|
||||||
- [`HierarchicalBeanFactory`](spring-factory/spring-factory-hierarchicalBeanFactory/README.md):支持父子容器关系,实现Bean定义的层次结构。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
|
- [`HierarchicalBeanFactory`](spring-factory/spring-factory-hierarchicalBeanFactory/README.md):支持父子容器关系,实现Bean定义的层次结构。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
|
||||||
|
|
||||||
- `ConfigurableBeanFactory`:提供对BeanFactory配置的扩展,如属性编辑器、作用域等。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
|
- [`ConfigurableBeanFactory`](spring-factory/spring-factory-configurableBeanFactory/README.md):提供对BeanFactory配置的扩展,如属性编辑器、作用域等。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
|
||||||
|
|
||||||
+ [`AutowireCapableBeanFactory`](spring-factory/spring-factory-autowireCapableBeanFactory/README.md):Bean创建、初始化、注入、销毁的核心功能接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
|
+ [`AutowireCapableBeanFactory`](spring-factory/spring-factory-autowireCapableBeanFactory/README.md):Bean创建、初始化、注入、销毁的核心功能接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
|
||||||
|
|
||||||
+ `ConfigurableListableBeanFactory`:支持配置和列表操作的可配置Bean工厂接口。<img src="https://img.shields.io/badge/%E5%8D%B3%E5%B0%86%E6%9B%B4%E6%96%B0-339933"></img>
|
+ [`ConfigurableListableBeanFactory`](spring-factory/spring-factory-configurableListableBeanFactory/README.md):支持配置和列表操作的可配置Bean工厂接口。<img src="https://img.shields.io/badge/Level-%E4%B8%80%E8%88%AC-%23FF6347"></img>
|
||||||
|
|
||||||
- 基于Java的配置
|
- 基于Java的配置
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,636 @@
|
||||||
|
## ConfigurableBeanFactory
|
||||||
|
|
||||||
|
- [ConfigurableBeanFactory](#configurablebeanfactory)
|
||||||
|
- [一、基本信息](#一基本信息)
|
||||||
|
- [二、基本描述](#二基本描述)
|
||||||
|
- [三、主要功能](#三主要功能)
|
||||||
|
- [四、接口源码](#四接口源码)
|
||||||
|
- [五、最佳实践](#五最佳实践)
|
||||||
|
- [六、与其他组件的关系](#六与其他组件的关系)
|
||||||
|
- [七、常见问题](#七常见问题)
|
||||||
|
|
||||||
|
### 一、基本信息
|
||||||
|
|
||||||
|
✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
|
||||||
|
|
||||||
|
### 二、基本描述
|
||||||
|
|
||||||
|
`ConfigurableBeanFactory`接口是Spring框架中的一个子接口,提供了一组方法用于在运行时配置和定制`BeanFactory`。通过这些方法,可以设置父级BeanFactory、类加载器、表达式解析器、类型转换服务等,以满足特定应用程序的需求。
|
||||||
|
|
||||||
|
### 三、主要功能
|
||||||
|
|
||||||
|
1. **设置父级BeanFactory (`setParentBeanFactory`)**
|
||||||
|
|
||||||
|
+ 允许将当前的`BeanFactory`与一个父级`BeanFactory`相关联,以实现Bean的继承和层次结构。
|
||||||
|
|
||||||
|
2. **设置Bean类加载器 (`setBeanClassLoader`)**
|
||||||
|
|
||||||
|
+ 允许指定用于加载Bean类的类加载器,使得可以在运行时动态加载Bean的类。
|
||||||
|
|
||||||
|
3. **设置临时的类加载器 (`setTempClassLoader`)**
|
||||||
|
|
||||||
|
+ 允许配置一个临时的类加载器,该加载器在需要时用于解析类,提供更灵活的类加载机制。
|
||||||
|
|
||||||
|
4. **配置是否缓存Bean元数据 (`setCacheBeanMetadata`)**
|
||||||
|
|
||||||
|
+ 允许我们配置是否缓存Bean的元数据,以提高性能。
|
||||||
|
|
||||||
|
5. **设置Bean表达式解析器 (`setBeanExpressionResolver`)**
|
||||||
|
|
||||||
|
+ 允许配置用于解析SpEL表达式的解析器,支持在Bean定义中使用Spring表达式语言。
|
||||||
|
|
||||||
|
6. **设置类型转换服务 (`setConversionService`)**
|
||||||
|
|
||||||
|
+ 允许配置用于处理属性类型转换的ConversionService,影响属性注入时的类型转换。
|
||||||
|
|
||||||
|
7. **注册PropertyEditorRegistrar (`addPropertyEditorRegistrar`)**
|
||||||
|
|
||||||
|
+ 允许注册自定义的PropertyEditorRegistrar,以便注册自定义的PropertyEditors,用于处理属性值的类型转换。
|
||||||
|
|
||||||
|
8. **设置自动装配候选Bean的解析器 (`setAutowireCandidateResolver`)**
|
||||||
|
|
||||||
|
+ 允许配置用于确定自动装配候选Bean的解析器,支持自定义自动装配策略。
|
||||||
|
|
||||||
|
9. **设置作用域别名 (`setScopeAlias`)**
|
||||||
|
|
||||||
|
+ 允许为指定的作用域设置别名,提供更灵活的作用域配置。
|
||||||
|
|
||||||
|
10. **注册Bean别名 (`registerAlias`)**
|
||||||
|
|
||||||
|
+ 允许注册给定Bean名称的别名,支持通过不同的名称引用相同的Bean。
|
||||||
|
|
||||||
|
11. **设置Bean后处理器 (`addBeanPostProcessor`)**
|
||||||
|
|
||||||
|
+ 允许注册自定义的Bean后处理器,用于在Bean初始化前后执行一些自定义逻辑。
|
||||||
|
|
||||||
|
12. **设置属性编辑器 (`registerCustomEditor`)**
|
||||||
|
|
||||||
|
+ 允许注册自定义的属性编辑器,用于将字符串值转换为特定属性类型。
|
||||||
|
|
||||||
|
13. **设置Bean名称生成器 (`setBeanNameGenerator`)**
|
||||||
|
|
||||||
|
+ 允许配置用于生成默认Bean名称的Bean名称生成器。
|
||||||
|
|
||||||
|
14. **设置范围解析器 (`setScopeResolver`)**
|
||||||
|
|
||||||
|
+ 允许配置用于解析范围的解析器,支持自定义作用域的处理逻辑。
|
||||||
|
|
||||||
|
15. **设置忽略依赖接口 (`ignoreDependencyInterface`)**
|
||||||
|
|
||||||
|
+ 允许配置需要被忽略的依赖接口,以避免它们被自动装配。
|
||||||
|
|
||||||
|
### 四、接口源码
|
||||||
|
|
||||||
|
`ConfigurableBeanFactory`接口是Spring框架中用于配置和定制Bean工厂的关键接口。它提供了设置父级Bean工厂、配置类加载器、设置Bean表达式解析器、注册自定义属性编辑器和后处理器、配置作用域等功能。
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* Configuration接口由大多数Bean工厂实现,提供配置Bean工厂的功能,除了{@link org.springframework.beans.factory.BeanFactory}接口中的客户端方法。
|
||||||
|
*
|
||||||
|
* <p>这个Bean工厂接口不是用于正常应用程序代码的:通常使用{@link org.springframework.beans.factory.BeanFactory}或{@link org.springframework.beans.factory.ListableBeanFactory}来满足典型需求。
|
||||||
|
* 这个扩展接口只是为了允许内部框架的插拔和对Bean工厂配置方法的特殊访问。
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 03.11.2003
|
||||||
|
* @see org.springframework.beans.factory.BeanFactory
|
||||||
|
* @see org.springframework.beans.factory.ListableBeanFactory
|
||||||
|
* @see ConfigurableListableBeanFactory
|
||||||
|
*/
|
||||||
|
public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, SingletonBeanRegistry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准单例范围的范围标识符:{@value}。
|
||||||
|
* <p>可以通过{@code registerScope}添加自定义范围。
|
||||||
|
* @see #registerScope
|
||||||
|
*/
|
||||||
|
String SCOPE_SINGLETON = "singleton";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标准原型范围的范围标识符:{@value}。
|
||||||
|
* <p>可以通过{@code registerScope}添加自定义范围。
|
||||||
|
* @see #registerScope
|
||||||
|
*/
|
||||||
|
String SCOPE_PROTOTYPE = "prototype";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置这个Bean工厂的父级。
|
||||||
|
* <p>请注意,父级不能更改:仅在构造函数之外设置,如果在工厂实例化时不可用。
|
||||||
|
* @param parentBeanFactory 父Bean工厂
|
||||||
|
* @throws IllegalStateException 如果此工厂已经与父Bean工厂关联
|
||||||
|
* @see #getParentBeanFactory()
|
||||||
|
*/
|
||||||
|
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置用于加载Bean类的类加载器。
|
||||||
|
* 默认为线程上下文类加载器。
|
||||||
|
* 注意,此类加载器仅适用于尚未解析Bean类的Bean定义。
|
||||||
|
* 这在Spring 2.0默认情况下是这样的:Bean定义只携带Bean类名称,一旦工厂处理Bean定义,就会解析Bean类。
|
||||||
|
* @param beanClassLoader 要使用的类加载器,如果为{@code null},则使用默认类加载器
|
||||||
|
*/
|
||||||
|
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用于加载Bean类的类加载器。
|
||||||
|
* (如果系统类加载器不可访问,甚至为{@code null})。
|
||||||
|
* @see org.springframework.util.ClassUtils#forName(String, ClassLoader)
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ClassLoader getBeanClassLoader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定用于类型匹配目的的临时ClassLoader。
|
||||||
|
* 默认为none,简单地使用标准Bean类ClassLoader。
|
||||||
|
* 通常,仅在涉及<load-time weaving>时才指定临时ClassLoader,
|
||||||
|
* 以确保实际的Bean类尽可能地懒加载。启动后,临时加载程序将被删除。
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
void setTempClassLoader(@Nullable ClassLoader tempClassLoader);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用于类型匹配目的的临时ClassLoader,如果有的话。
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ClassLoader getTempClassLoader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置是否缓存诸如给定Bean定义(以合并方式)和已解析Bean类等Bean元数据。
|
||||||
|
* 默认为开。
|
||||||
|
* 关闭此标志以启用Bean定义对象和特别是Bean类的热刷新。如果关闭此标志,任何创建Bean实例都将重新查询Bean类加载程序以获取新解析的类。
|
||||||
|
*/
|
||||||
|
void setCacheBeanMetadata(boolean cacheBeanMetadata);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回是否缓存诸如给定Bean定义(以合并方式)和已解析Bean类等Bean元数据。
|
||||||
|
*/
|
||||||
|
boolean isCacheBeanMetadata();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定Bean定义值中表达式的解析策略。
|
||||||
|
* <p>默认情况下,Bean工厂中没有激活表达式支持。
|
||||||
|
* ApplicationContext通常在这里设置标准的表达式策略,支持统一EL兼容样式的“#{...}”表达式。
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
void setBeanExpressionResolver(@Nullable BeanExpressionResolver resolver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回Bean定义值中表达式的解析策略。
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
BeanExpressionResolver getBeanExpressionResolver();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 指定用于转换属性值的Spring 3.0 ConversionService,作为JavaBeans PropertyEditors的替代方法。
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
void setConversionService(@Nullable ConversionService conversionService);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回关联的ConversionService,如果有的话。
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
ConversionService getConversionService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加一个PropertyEditorRegistrar,应用于所有Bean创建过程。
|
||||||
|
* <p>此类注册器创建新的PropertyEditor实例,并为每个Bean创建尝试将其注册在给定的注册表上。这避免了对自定义编辑器的同步的需求;
|
||||||
|
* 因此,通常最好使用此方法,而不是{@link #registerCustomEditor}。
|
||||||
|
* @param registrar 要注册的PropertyEditorRegistrar
|
||||||
|
*/
|
||||||
|
void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册给定类型的所有属性的自定义属性编辑器。在工厂配置期间调用。
|
||||||
|
* <p>请注意,此方法将注册共享的自定义编辑器实例;对该实例的访问将同步以确保线程安全。通常最好使用{@link #addPropertyEditorRegistrar},
|
||||||
|
* 而不是此方法,以避免在自定义编辑器上进行同步的需求。
|
||||||
|
* @param requiredType 属性的类型
|
||||||
|
* @param propertyEditorClass 要注册的{@link PropertyEditor}类
|
||||||
|
*/
|
||||||
|
void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用在此BeanFactory中注册的自定义编辑器初始化给定的PropertyEditorRegistry。
|
||||||
|
* @param registry 要初始化的PropertyEditorRegistry
|
||||||
|
*/
|
||||||
|
void copyRegisteredEditorsTo(PropertyEditorRegistry registry);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置此BeanFactory应该用于转换Bean属性值、构造函数参数值等的自定义类型转换器。
|
||||||
|
* <p>这将覆盖默认的PropertyEditor机制,因此任何自定义编辑器或自定义编辑器注册器都将变得无关紧要。
|
||||||
|
* @since 2.5
|
||||||
|
* @see #addPropertyEditorRegistrar
|
||||||
|
* @see #registerCustomEditor
|
||||||
|
*/
|
||||||
|
void setTypeConverter(TypeConverter typeConverter);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取此BeanFactory使用的类型转换器。每次调用可能都是新实例,因为TypeConverter通常不是线程安全的。
|
||||||
|
* <p>如果默认的PropertyEditor机制处于活动状态,返回的TypeConverter将意识到已注册的所有自定义编辑器。
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
TypeConverter getTypeConverter();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加用于嵌入值(如注释属性)的String解析器。
|
||||||
|
* @param valueResolver 要应用于嵌入值的String解析器
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
void addEmbeddedValueResolver(StringValueResolver valueResolver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定是否已向此工厂注册了嵌入值解析器,以通过{@link #resolveEmbeddedValue(String)}应用它们。
|
||||||
|
* @since 4.3
|
||||||
|
*/
|
||||||
|
boolean hasEmbeddedValueResolver();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析给定的嵌入值,例如注解属性。
|
||||||
|
* @param value 要解析的值
|
||||||
|
* @return 已解析的值(可能是原始值)
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
String resolveEmbeddedValue(String value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加将应用于此工厂创建的所有Bean的新BeanPostProcessor。
|
||||||
|
* 在工厂配置期间调用。
|
||||||
|
* <p>注意:此处提交的后处理器将按照注册的顺序应用;通过实现{@link org.springframework.core.Ordered}接口表达的任何排序语义将被忽略。
|
||||||
|
* 请注意,在自动检测到的后处理器(例如,作为应用程序上下文中的bean)之后,总是会应用程序地注册的后处理器。
|
||||||
|
* @param beanPostProcessor 要注册的后处理器
|
||||||
|
*/
|
||||||
|
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回当前已注册的BeanPostProcessor数量,如果有的话。
|
||||||
|
*/
|
||||||
|
int getBeanPostProcessorCount();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册给定的范围,由给定的Scope实现支持。
|
||||||
|
* @param scopeName 范围标识符
|
||||||
|
* @param scope 支持的Scope实现
|
||||||
|
*/
|
||||||
|
void registerScope(String scopeName, Scope scope);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回当前已注册的所有Scope的名称。
|
||||||
|
* <p>这将仅返回明确注册的范围名称。内置范围,如“singleton”和“prototype”将不会被公开。
|
||||||
|
* @return 范围名称的数组,如果没有则为空数组
|
||||||
|
* @see #registerScope
|
||||||
|
*/
|
||||||
|
String[] getRegisteredScopeNames();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回给定范围名称的Scope实现,如果有的话。
|
||||||
|
* <p>这将仅返回明确注册的范围。
|
||||||
|
* 内置范围,如“singleton”和“prototype”将不会被公开。
|
||||||
|
* @param scopeName 范围的名称
|
||||||
|
* @return 注册的Scope实现,如果没有则为{@code null}
|
||||||
|
* @see #registerScope
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Scope getRegisteredScope(String scopeName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为此Bean工厂设置{@code ApplicationStartup}。
|
||||||
|
* <p>这允许应用程序上下文在应用程序启动期间记录度量。
|
||||||
|
* @param applicationStartup 新的应用程序启动
|
||||||
|
* @since 5.3
|
||||||
|
*/
|
||||||
|
void setApplicationStartup(ApplicationStartup applicationStartup);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此Bean工厂的{@code ApplicationStartup}。
|
||||||
|
* @since 5.3
|
||||||
|
*/
|
||||||
|
ApplicationStartup getApplicationStartup();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提供与此工厂相关的安全访问控制上下文。
|
||||||
|
* @return 适用的AccessControlContext(永远不为{@code null})
|
||||||
|
* @since 3.0
|
||||||
|
*/
|
||||||
|
AccessControlContext getAccessControlContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从给定的其他工厂复制所有相关配置。
|
||||||
|
* <p>应包括所有标准配置设置,以及BeanPostProcessors、Scopes和工厂特定的内部设置。
|
||||||
|
* 不应包括任何实际Bean定义的元数据,如BeanDefinition对象和Bean名称别名。
|
||||||
|
* @param otherFactory 要从中复制的其他Bean工厂
|
||||||
|
*/
|
||||||
|
void copyConfigurationFrom(ConfigurableBeanFactory otherFactory);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 给定一个bean名称,创建一个别名。通常在工厂配置期间调用此方法,但也可以用于别名的运行时注册。因此,工厂实现应该同步别名访问。
|
||||||
|
*
|
||||||
|
* @param beanName 目标bean的规范名称
|
||||||
|
* @param alias 要为bean注册的别名
|
||||||
|
* @throws BeanDefinitionStoreException 如果别名已经被使用
|
||||||
|
*/
|
||||||
|
void registerAlias(String beanName, String alias) throws BeanDefinitionStoreException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析在此工厂中注册的所有别名目标名称和别名,将给定的StringValueResolver应用于它们。
|
||||||
|
* 值解析器可以解析目标bean名称中的占位符,甚至是别名中的占位符。
|
||||||
|
*
|
||||||
|
* @param valueResolver 要应用的StringValueResolver
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
void resolveAliases(StringValueResolver valueResolver);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回给定bean名称的合并BeanDefinition,如果需要,将子bean定义与其父定义合并。考虑在祖先工厂中的bean定义。
|
||||||
|
*
|
||||||
|
* @param beanName 要检索合并定义的bean的名称
|
||||||
|
* @return 给定bean的(可能合并的)BeanDefinition
|
||||||
|
* @throws NoSuchBeanDefinitionException 如果没有给定名称的bean定义
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定具有给定名称的bean是否是FactoryBean。
|
||||||
|
*
|
||||||
|
* @param name 要检查的bean的名称
|
||||||
|
* @return bean是否是FactoryBean({@code false}表示bean存在但不是FactoryBean)
|
||||||
|
* @throws NoSuchBeanDefinitionException 如果没有给定名称的bean
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
boolean isFactoryBean(String name) throws NoSuchBeanDefinitionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显式控制指定bean的当前创建状态。仅供容器内部使用。
|
||||||
|
*
|
||||||
|
* @param beanName bean的名称
|
||||||
|
* @param inCreation bean当前是否正在创建
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
void setCurrentlyInCreation(String beanName, boolean inCreation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定指定的bean当前是否正在创建。
|
||||||
|
*
|
||||||
|
* @param beanName bean的名称
|
||||||
|
* @return bean当前是否正在创建
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
boolean isCurrentlyInCreation(String beanName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 为给定的bean注册一个依赖bean,该依赖bean在给定bean被销毁之前将被销毁。
|
||||||
|
*
|
||||||
|
* @param beanName bean的名称
|
||||||
|
* @param dependentBeanName 依赖bean的名称
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
void registerDependentBean(String beanName, String dependentBeanName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回所有依赖于指定bean的bean的名称(如果有的话)。
|
||||||
|
*
|
||||||
|
* @param beanName bean的名称
|
||||||
|
* @return 依赖bean名称的数组,如果没有则为空数组
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
String[] getDependentBeans(String beanName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回指定bean依赖的所有bean的名称(如果有的话)。
|
||||||
|
*
|
||||||
|
* @param beanName bean的名称
|
||||||
|
* @return bean依赖的bean名称数组,如果没有则为空数组
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
String[] getDependenciesForBean(String beanName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据其bean定义销毁给定的bean实例(通常是从此工厂获得的原型实例)。
|
||||||
|
* <p>销毁期间出现的任何异常都应捕获并记录,而不是传播到此方法的调用者。
|
||||||
|
*
|
||||||
|
* @param beanName bean定义的名称
|
||||||
|
* @param beanInstance 要销毁的bean实例
|
||||||
|
*/
|
||||||
|
void destroyBean(String beanName, Object beanInstance);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 在当前目标作用域中销毁指定的作用域bean,如果有的话。
|
||||||
|
* <p>销毁期间出现的任何异常都应捕获并记录,而不是传播到此方法的调用者。
|
||||||
|
*
|
||||||
|
* @param beanName 作用域bean的名称
|
||||||
|
*/
|
||||||
|
void destroyScopedBean(String beanName);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 销毁此工厂中的所有单例bean,包括已注册为可销毁的内部bean。在工厂关闭时调用。
|
||||||
|
* <p>销毁期间出现的任何异常都应捕获并记录,而不是传播到此方法的调用者。
|
||||||
|
*/
|
||||||
|
void destroySingletons();
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 五、最佳实践
|
||||||
|
|
||||||
|
演示了`ConfigurableBeanFactory`接口的一些常用方法。包括设置父级BeanFactory、获取BeanPostProcessor数量、注册别名、处理依赖关系等。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ConfigurableBeanFactoryDemo {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 创建 ApplicationContext
|
||||||
|
ConfigurableBeanFactory configurableBeanFactory = new AnnotationConfigApplicationContext(MyConfiguration.class).getBeanFactory();
|
||||||
|
|
||||||
|
// 设置父级 BeanFactory
|
||||||
|
configurableBeanFactory.setParentBeanFactory(new DefaultListableBeanFactory());
|
||||||
|
|
||||||
|
// 获取BeanPostProcessor数量
|
||||||
|
int beanPostProcessorCount = configurableBeanFactory.getBeanPostProcessorCount();
|
||||||
|
System.out.println("获取BeanPostProcessor数量: " + beanPostProcessorCount);
|
||||||
|
|
||||||
|
// 获取所有已注册的 Scope 名称
|
||||||
|
String[] scopeNames = configurableBeanFactory.getRegisteredScopeNames();
|
||||||
|
System.out.println("获取所有已注册的Scope名称: " + String.join(", ", scopeNames));
|
||||||
|
|
||||||
|
// 获取注册的 Scope
|
||||||
|
Scope customScope = configurableBeanFactory.getRegisteredScope("customScope");
|
||||||
|
System.out.println("获取注册的Scope :" + customScope);
|
||||||
|
|
||||||
|
// 获取ApplicationStartup
|
||||||
|
ApplicationStartup applicationStartup = configurableBeanFactory.getApplicationStartup();
|
||||||
|
System.out.println("获取ApplicationStartup: " + applicationStartup);
|
||||||
|
|
||||||
|
// 获取AccessControlContext
|
||||||
|
AccessControlContext accessControlContext = configurableBeanFactory.getAccessControlContext();
|
||||||
|
System.out.println("获取AccessControlContext: " + accessControlContext);
|
||||||
|
|
||||||
|
// 拷贝配置
|
||||||
|
ConfigurableListableBeanFactory otherFactory = new DefaultListableBeanFactory();
|
||||||
|
configurableBeanFactory.copyConfigurationFrom(otherFactory);
|
||||||
|
System.out.println("拷贝配置copyConfigurationFrom: " + otherFactory);
|
||||||
|
|
||||||
|
// 注册别名
|
||||||
|
String beanName = "myService";
|
||||||
|
String alias = "helloService";
|
||||||
|
configurableBeanFactory.registerAlias(beanName, alias);
|
||||||
|
System.out.println("注册别名registerAlias, BeanName: " + beanName + "alias: " + alias);
|
||||||
|
|
||||||
|
// 获取合并后的 BeanDefinition
|
||||||
|
BeanDefinition mergedBeanDefinition = configurableBeanFactory.getMergedBeanDefinition("myService");
|
||||||
|
System.out.println("获取合并后的 BeanDefinition: " + mergedBeanDefinition);
|
||||||
|
|
||||||
|
// 判断是否为 FactoryBean
|
||||||
|
String factoryBeanName = "myService";
|
||||||
|
boolean isFactoryBean = configurableBeanFactory.isFactoryBean(factoryBeanName);
|
||||||
|
System.out.println("判断是否为FactoryBean" + isFactoryBean);
|
||||||
|
|
||||||
|
// 设置当前 Bean 是否正在创建
|
||||||
|
String currentBeanName = "myService";
|
||||||
|
boolean inCreation = true;
|
||||||
|
configurableBeanFactory.setCurrentlyInCreation(currentBeanName, inCreation);
|
||||||
|
System.out.println("设置当前Bean是否正在创建: " + currentBeanName);
|
||||||
|
|
||||||
|
// 判断指定的 Bean 是否正在创建
|
||||||
|
boolean isCurrentlyInCreation = configurableBeanFactory.isCurrentlyInCreation(currentBeanName);
|
||||||
|
System.out.println("判断指定的Bean是否正在创建" + isCurrentlyInCreation);
|
||||||
|
|
||||||
|
// 注册依赖关系
|
||||||
|
String dependentBeanName = "dependentBean";
|
||||||
|
configurableBeanFactory.registerDependentBean(beanName, dependentBeanName);
|
||||||
|
System.out.println("注册依赖关系" + "beanName: " + beanName + "dependentBeanName: " + dependentBeanName);
|
||||||
|
|
||||||
|
// 获取所有依赖于指定 Bean 的 Bean 名称
|
||||||
|
String[] dependentBeans = configurableBeanFactory.getDependentBeans(beanName);
|
||||||
|
System.out.println("获取所有依赖于指定Bean的Bean名称: " + String.join(", ", dependentBeans));
|
||||||
|
|
||||||
|
// 获取指定 Bean 依赖的所有 Bean 名称
|
||||||
|
String[] dependencies = configurableBeanFactory.getDependenciesForBean(beanName);
|
||||||
|
System.out.println("获取指定Bean依赖的所有Bean名称: " + String.join(", ", dependencies));
|
||||||
|
|
||||||
|
// 销毁指定 Bean 实例
|
||||||
|
Object beanInstance = configurableBeanFactory.getBean(beanName);
|
||||||
|
configurableBeanFactory.destroyBean(beanName, beanInstance);
|
||||||
|
System.out.println("销毁指定 Bean 实例: " + beanName);
|
||||||
|
|
||||||
|
// 销毁所有单例 Bean
|
||||||
|
configurableBeanFactory.destroySingletons();
|
||||||
|
System.out.println("销毁所有单例Bean destroySingletons" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 六、与其他组件的关系
|
||||||
|
|
||||||
|
1. **BeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 继承自 `BeanFactory` 接口,因此它包含了 `BeanFactory` 的基本功能。它扩展了 `BeanFactory` 接口,提供了更多的配置和管理功能。
|
||||||
|
|
||||||
|
2. **HierarchicalBeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 扩展了 `HierarchicalBeanFactory` 接口,因此它具有层次结构的特性。这允许配置一个父级 `BeanFactory`,从而实现层次化的容器结构。
|
||||||
|
|
||||||
|
3. **SingletonBeanRegistry**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 扩展了 `SingletonBeanRegistry` 接口,使其能够注册和管理单例对象。这包括对单例对象的创建、获取和销毁等操作。
|
||||||
|
|
||||||
|
4. **BeanPostProcessor**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许注册 `BeanPostProcessor` 实现,这些实现可以在容器中的 bean 实例创建和初始化阶段进行干预。通过 `addBeanPostProcessor` 方法,可以向容器注册自定义的 `BeanPostProcessor` 实现。
|
||||||
|
|
||||||
|
5. **Scope**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 定义了注册和获取作用域的方法。可以通过 `registerScope` 注册自定义作用域,并通过 `getRegisteredScope` 获取已注册的作用域。
|
||||||
|
|
||||||
|
6. **ConversionService**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许设置和获取 `ConversionService`,用于执行属性值的类型转换。通过 `setConversionService` 和 `getConversionService` 方法,可以配置和检索自定义的类型转换服务。
|
||||||
|
|
||||||
|
7. **BeanExpressionResolver**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许设置和获取 `BeanExpressionResolver`,用于解析 bean 定义中的表达式。通过 `setBeanExpressionResolver` 和 `getBeanExpressionResolver` 方法,可以配置和获取表达式解析器。
|
||||||
|
|
||||||
|
8. **TypeConverter**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许设置和获取 `TypeConverter`,用于执行 bean 属性值的类型转换。通过 `setTypeConverter` 和 `getTypeConverter` 方法,可以配置和获取类型转换器。
|
||||||
|
|
||||||
|
9. **StringValueResolver**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许添加和检查字符串值解析器,用于解析 bean 定义中的嵌入式值。通过 `addEmbeddedValueResolver` 和 `hasEmbeddedValueResolver` 方法,可以进行相应的操作。
|
||||||
|
|
||||||
|
10. **PropertyEditorRegistrar**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许添加 `PropertyEditorRegistrar`,用于注册自定义的 `PropertyEditor`。通过 `addPropertyEditorRegistrar` 方法,可以注册属性编辑器注册器。
|
||||||
|
|
||||||
|
11. **ApplicationStartup**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许设置和获取 `ApplicationStartup`,用于记录应用程序启动期间的度量。通过 `setApplicationStartup` 和 `getApplicationStartup` 方法,可以配置和获取启动度量实例。
|
||||||
|
|
||||||
|
12. **AccessControlContext**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 允许获取与该工厂相关的安全访问控制上下文。通过 `getAccessControlContext` 方法,可以获取安全访问控制上下文。
|
||||||
|
|
||||||
|
13. **AliasRegistry**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 继承了 `AliasRegistry` 接口,因此它也提供了对别名的注册和解析的功能。可以通过 `registerAlias` 和 `resolveAliases` 方法进行别名的注册和解析。
|
||||||
|
|
||||||
|
14. **ConfigurableListableBeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 是 `ConfigurableListableBeanFactory` 的父接口。`ConfigurableListableBeanFactory` 除了提供配置和管理功能外,还允许对 bean 定义进行查询,包括合并的 bean 定义等。
|
||||||
|
|
||||||
|
### 七、常见问题
|
||||||
|
|
||||||
|
1. **什么是 ConfigurableBeanFactory 接口的作用?**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 接口是 Spring 框架中 IoC 容器的配置接口之一。它扩展了 `BeanFactory` 接口,提供了一系列用于配置和管理 IoC 容器的方法,如设置父容器、注册作用域、添加 BeanPostProcessor 等。
|
||||||
|
|
||||||
|
2. **ConfigurableBeanFactory 与 BeanFactory 有什么区别?**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 继承自 `BeanFactory` 接口,相比于 `BeanFactory`,它提供了更多的配置和管理方法。通过 `ConfigurableBeanFactory`,可以设置父容器、注册作用域、添加 BeanPostProcessor 等,而 `BeanFactory` 只提供了基本的 bean 获取和类型检查的功能。
|
||||||
|
|
||||||
|
3. **如何设置 ConfigurableBeanFactory 的父容器?**
|
||||||
|
|
||||||
|
- 可以使用 `setParentBeanFactory` 方法来设置 `ConfigurableBeanFactory` 的父容器。通过这个方法,可以建立容器的层次结构,实现父子容器之间的资源共享和依赖管理。
|
||||||
|
|
||||||
|
4. **ConfigurableBeanFactory 中的 Scope 是什么作用?**
|
||||||
|
|
||||||
|
- `ConfigurableBeanFactory` 中的 Scope 用于定义和管理 bean 的作用域。作用域决定了 bean 的生命周期和可见范围,例如 singleton 作用域表示一个 bean 在容器中是单例的,而 prototype 作用域表示每次获取 bean 都会创建一个新实例。
|
||||||
|
|
||||||
|
5. **如何注册自定义的 Scope?**
|
||||||
|
|
||||||
|
- 可以使用 `registerScope` 方法来注册自定义的作用域。通过该方法,可以添加自定义作用域的实现,并在容器中使用该作用域。
|
||||||
|
|
||||||
|
6. **ConfigurableBeanFactory 中的 BeanPostProcessor 有什么作用?**
|
||||||
|
|
||||||
|
- `BeanPostProcessor` 在 bean 的创建和初始化阶段起作用,允许我们对 bean 进行定制和干预。通过 `addBeanPostProcessor` 方法,可以注册自定义的 `BeanPostProcessor` 实现。
|
||||||
|
|
||||||
|
7. **如何设置 ConfigurableBeanFactory 的 ClassLoader?**
|
||||||
|
|
||||||
|
- 可以使用 `setBeanClassLoader` 方法来设置 `ConfigurableBeanFactory` 的 ClassLoader。这个 ClassLoader 用于加载 bean 的类,可以指定一个特定的 ClassLoader,也可以使用默认的线程上下文 ClassLoader。
|
||||||
|
|
||||||
|
8. **ConfigurableBeanFactory 中的 ConversionService 有什么作用?**
|
||||||
|
|
||||||
|
- `ConversionService` 用于执行 bean 属性值的类型转换。通过 `setConversionService` 方法,可以设置自定义的类型转换服务,用于处理 bean 属性值的类型转换。
|
||||||
|
|
||||||
|
9. **如何配置 ConfigurableBeanFactory 中的 BeanExpressionResolver?**
|
||||||
|
|
||||||
|
- 可以使用 `setBeanExpressionResolver` 方法来配置 `ConfigurableBeanFactory` 中的 `BeanExpressionResolver`。这个解析器用于解析 bean 定义中的表达式,例如 Spring EL 表达式。
|
||||||
|
|
||||||
|
10. **ConfigurableBeanFactory 中的 TypeConverter 有什么作用?**
|
||||||
|
|
||||||
|
- `TypeConverter` 用于执行 bean 属性值的类型转换。通过 `setTypeConverter` 方法,可以设置自定义的类型转换器,用于处理 bean 属性值的类型转换。
|
||||||
|
|
||||||
|
11. **如何注册 ConfigurableBeanFactory 的 PropertyEditorRegistrar?**
|
||||||
|
|
||||||
|
- 可以使用 `addPropertyEditorRegistrar` 方法来注册 `ConfigurableBeanFactory` 的 `PropertyEditorRegistrar`。这个注册器用于注册自定义的 `PropertyEditor`,处理属性编辑器的创建和注册。
|
||||||
|
|
||||||
|
12. **ConfigurableBeanFactory 中的 ApplicationStartup 有什么作用?**
|
||||||
|
|
||||||
|
- `ApplicationStartup` 用于记录应用程序启动期间的度量。通过 `setApplicationStartup` 方法,可以设置自定义的 `ApplicationStartup` 实例,用于记录启动度量。
|
||||||
|
|
||||||
|
13. **ConfigurableBeanFactory 中的 destroySingletons 方法有什么作用?**
|
||||||
|
|
||||||
|
- `destroySingletons` 方法用于销毁所有单例 bean,包括内部注册为可销毁的 bean。这个方法通常在容器关闭时调用,用于释放资源和执行清理操作。
|
|
@ -21,115 +21,80 @@ public class ConfigurableBeanFactoryDemo {
|
||||||
// 创建 ApplicationContext
|
// 创建 ApplicationContext
|
||||||
ConfigurableBeanFactory configurableBeanFactory = new AnnotationConfigApplicationContext(MyConfiguration.class).getBeanFactory();
|
ConfigurableBeanFactory configurableBeanFactory = new AnnotationConfigApplicationContext(MyConfiguration.class).getBeanFactory();
|
||||||
|
|
||||||
// 示例:设置父级 BeanFactory
|
// 设置父级 BeanFactory
|
||||||
configurableBeanFactory.setParentBeanFactory(new DefaultListableBeanFactory());
|
configurableBeanFactory.setParentBeanFactory(new DefaultListableBeanFactory());
|
||||||
|
|
||||||
// 示例:设置 ClassLoader
|
// 获取BeanPostProcessor数量
|
||||||
configurableBeanFactory.setBeanClassLoader(ConfigurableBeanFactoryDemo.class.getClassLoader());
|
|
||||||
|
|
||||||
// 示例:设置临时 ClassLoader
|
|
||||||
configurableBeanFactory.setTempClassLoader(Thread.currentThread().getContextClassLoader());
|
|
||||||
|
|
||||||
// 示例:设置是否缓存 bean metadata
|
|
||||||
configurableBeanFactory.setCacheBeanMetadata(true);
|
|
||||||
|
|
||||||
// 示例:获取BeanPostProcessor数量
|
|
||||||
int beanPostProcessorCount = configurableBeanFactory.getBeanPostProcessorCount();
|
int beanPostProcessorCount = configurableBeanFactory.getBeanPostProcessorCount();
|
||||||
System.out.println("1.BeanPostProcessor 数量: " + beanPostProcessorCount);
|
System.out.println("获取BeanPostProcessor数量: " + beanPostProcessorCount);
|
||||||
|
|
||||||
// 示例:获取所有已注册的 Scope 名称
|
// 获取所有已注册的 Scope 名称
|
||||||
String[] scopeNames = configurableBeanFactory.getRegisteredScopeNames();
|
String[] scopeNames = configurableBeanFactory.getRegisteredScopeNames();
|
||||||
System.out.println("2.已注册的 Scope 名称: " + String.join(", ", scopeNames));
|
System.out.println("获取所有已注册的Scope名称: " + String.join(", ", scopeNames));
|
||||||
|
|
||||||
// 示例:获取注册的 Scope
|
// 获取注册的 Scope
|
||||||
String customScopeName = "customScope";
|
Scope customScope = configurableBeanFactory.getRegisteredScope("customScope");
|
||||||
Scope customScope = configurableBeanFactory.getRegisteredScope(customScopeName);
|
System.out.println("获取注册的Scope :" + customScope);
|
||||||
System.out.println("3." + customScopeName + " 对应的 Scope: " + customScope);
|
|
||||||
|
|
||||||
// 示例:获取 ApplicationStartup
|
// 获取ApplicationStartup
|
||||||
ApplicationStartup applicationStartup = configurableBeanFactory.getApplicationStartup();
|
ApplicationStartup applicationStartup = configurableBeanFactory.getApplicationStartup();
|
||||||
System.out.println("4.ApplicationStartup: " + applicationStartup);
|
System.out.println("获取ApplicationStartup: " + applicationStartup);
|
||||||
|
|
||||||
// 示例:获取 AccessControlContext
|
// 获取AccessControlContext
|
||||||
AccessControlContext accessControlContext = configurableBeanFactory.getAccessControlContext();
|
AccessControlContext accessControlContext = configurableBeanFactory.getAccessControlContext();
|
||||||
System.out.println("5.AccessControlContext: " + accessControlContext);
|
System.out.println("获取AccessControlContext: " + accessControlContext);
|
||||||
|
|
||||||
// 示例:拷贝配置
|
// 拷贝配置
|
||||||
ConfigurableListableBeanFactory otherFactory = new DefaultListableBeanFactory();
|
ConfigurableListableBeanFactory otherFactory = new DefaultListableBeanFactory();
|
||||||
configurableBeanFactory.copyConfigurationFrom(otherFactory);
|
configurableBeanFactory.copyConfigurationFrom(otherFactory);
|
||||||
|
System.out.println("拷贝配置copyConfigurationFrom: " + otherFactory);
|
||||||
|
|
||||||
// 示例:注册别名
|
// 注册别名
|
||||||
String beanName = "myService";
|
String beanName = "myService";
|
||||||
String alias = "helloService";
|
String alias = "helloService";
|
||||||
configurableBeanFactory.registerAlias(beanName, alias);
|
configurableBeanFactory.registerAlias(beanName, alias);
|
||||||
|
System.out.println("注册别名registerAlias, BeanName: " + beanName + "alias: " + alias);
|
||||||
|
|
||||||
// 示例:解析别名
|
// 获取合并后的 BeanDefinition
|
||||||
configurableBeanFactory.resolveAliases(value -> value + "_resolved");
|
BeanDefinition mergedBeanDefinition = configurableBeanFactory.getMergedBeanDefinition("myService");
|
||||||
|
System.out.println("获取合并后的 BeanDefinition: " + mergedBeanDefinition);
|
||||||
|
|
||||||
// 示例:获取合并后的 BeanDefinition
|
// 判断是否为 FactoryBean
|
||||||
String mergedBeanName = "myService";
|
|
||||||
BeanDefinition mergedBeanDefinition = configurableBeanFactory.getMergedBeanDefinition(mergedBeanName);
|
|
||||||
System.out.println("6.合并后的 BeanDefinition: " + mergedBeanDefinition);
|
|
||||||
|
|
||||||
// 示例:判断是否为 FactoryBean
|
|
||||||
String factoryBeanName = "myService";
|
String factoryBeanName = "myService";
|
||||||
boolean isFactoryBean = configurableBeanFactory.isFactoryBean(factoryBeanName);
|
boolean isFactoryBean = configurableBeanFactory.isFactoryBean(factoryBeanName);
|
||||||
System.out.println("7." + factoryBeanName + " 是否为 FactoryBean: " + isFactoryBean);
|
System.out.println("判断是否为FactoryBean" + isFactoryBean);
|
||||||
|
|
||||||
// 示例:设置当前 Bean 是否正在创建
|
// 设置当前 Bean 是否正在创建
|
||||||
String currentBeanName = "myService";
|
String currentBeanName = "myService";
|
||||||
boolean inCreation = true;
|
boolean inCreation = true;
|
||||||
configurableBeanFactory.setCurrentlyInCreation(currentBeanName, inCreation);
|
configurableBeanFactory.setCurrentlyInCreation(currentBeanName, inCreation);
|
||||||
|
System.out.println("设置当前Bean是否正在创建: " + currentBeanName);
|
||||||
|
|
||||||
// 示例:判断指定的 Bean 是否正在创建
|
// 判断指定的 Bean 是否正在创建
|
||||||
boolean isCurrentlyInCreation = configurableBeanFactory.isCurrentlyInCreation(currentBeanName);
|
boolean isCurrentlyInCreation = configurableBeanFactory.isCurrentlyInCreation(currentBeanName);
|
||||||
System.out.println("8." + currentBeanName + " 是否正在创建: " + isCurrentlyInCreation);
|
System.out.println("判断指定的Bean是否正在创建" + isCurrentlyInCreation);
|
||||||
|
|
||||||
// 示例:注册依赖关系
|
// 注册依赖关系
|
||||||
String dependentBeanName = "dependentBean";
|
String dependentBeanName = "dependentBean";
|
||||||
configurableBeanFactory.registerDependentBean(beanName, dependentBeanName);
|
configurableBeanFactory.registerDependentBean(beanName, dependentBeanName);
|
||||||
|
System.out.println("注册依赖关系" + "beanName: " + beanName + "dependentBeanName: " + dependentBeanName);
|
||||||
|
|
||||||
// 示例:获取所有依赖于指定 Bean 的 Bean 名称
|
// 获取所有依赖于指定 Bean 的 Bean 名称
|
||||||
String[] dependentBeans = configurableBeanFactory.getDependentBeans(beanName);
|
String[] dependentBeans = configurableBeanFactory.getDependentBeans(beanName);
|
||||||
System.out.println("9." + beanName + " 的所有依赖 Bean 名称: " + String.join(", ", dependentBeans));
|
System.out.println("获取所有依赖于指定Bean的Bean名称: " + String.join(", ", dependentBeans));
|
||||||
|
|
||||||
// 示例:获取指定 Bean 依赖的所有 Bean 名称
|
// 获取指定 Bean 依赖的所有 Bean 名称
|
||||||
String[] dependencies = configurableBeanFactory.getDependenciesForBean(beanName);
|
String[] dependencies = configurableBeanFactory.getDependenciesForBean(beanName);
|
||||||
System.out.println("10." + beanName + " 依赖的所有 Bean 名称: " + String.join(", ", dependencies));
|
System.out.println("获取指定Bean依赖的所有Bean名称: " + String.join(", ", dependencies));
|
||||||
|
|
||||||
// 销毁指定 Bean 实例
|
// 销毁指定 Bean 实例
|
||||||
Object beanInstance = configurableBeanFactory.getBean(beanName);
|
Object beanInstance = configurableBeanFactory.getBean(beanName);
|
||||||
configurableBeanFactory.destroyBean(beanName, beanInstance);
|
configurableBeanFactory.destroyBean(beanName, beanInstance);
|
||||||
|
System.out.println("销毁指定 Bean 实例: " + beanName);
|
||||||
|
|
||||||
// 销毁所有单例 Bean
|
// 销毁所有单例 Bean
|
||||||
configurableBeanFactory.destroySingletons();
|
configurableBeanFactory.destroySingletons();
|
||||||
|
System.out.println("销毁所有单例Bean destroySingletons" );
|
||||||
// 示例:添加 PropertyEditorRegistrar
|
|
||||||
// configurableBeanFactory.addPropertyEditorRegistrar(null);
|
|
||||||
|
|
||||||
// 示例:注册自定义 PropertyEditor
|
|
||||||
// configurableBeanFactory.registerCustomEditor(String.class, null);
|
|
||||||
|
|
||||||
// 示例:添加 StringValueResolver
|
|
||||||
// configurableBeanFactory.addEmbeddedValueResolver(null);
|
|
||||||
|
|
||||||
// 示例:添加 BeanPostProcessor
|
|
||||||
// configurableBeanFactory.addBeanPostProcessor(null);
|
|
||||||
|
|
||||||
// 示例:注册 Scope
|
|
||||||
// configurableBeanFactory.registerScope("customScope", null);
|
|
||||||
|
|
||||||
// 示例:设置 ApplicationStartup
|
|
||||||
// configurableBeanFactory.setApplicationStartup(null);
|
|
||||||
|
|
||||||
// 示例:设置 Bean 表达式解析器
|
|
||||||
// configurableBeanFactory.setBeanExpressionResolver(null);
|
|
||||||
|
|
||||||
// 示例:设置 ConversionService
|
|
||||||
// configurableBeanFactory.setConversionService(null);
|
|
||||||
|
|
||||||
// 示例:设置 TypeConverter
|
|
||||||
// configurableBeanFactory.setTypeConverter(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,297 @@
|
||||||
|
## ConfigurableListableBeanFactory
|
||||||
|
|
||||||
|
- [ConfigurableListableBeanFactory](#configurablelistablebeanfactory)
|
||||||
|
- [一、基本信息](#一基本信息)
|
||||||
|
- [二、基本描述](#二基本描述)
|
||||||
|
- [三、主要功能](#三主要功能)
|
||||||
|
- [四、接口源码](#四接口源码)
|
||||||
|
- [五、最佳实践](#五最佳实践)
|
||||||
|
- [六、与其他组件的关系](#六与其他组件的关系)
|
||||||
|
- [七、常见问题](#七常见问题)
|
||||||
|
|
||||||
|
### 一、基本信息
|
||||||
|
|
||||||
|
✒️ **作者** - Lex 📝 **博客** - [掘金](https://juejin.cn/user/4251135018533068/posts) 📚 **源码地址** - [github](https://github.com/xuchengsheng/spring-reading)
|
||||||
|
|
||||||
|
### 二、基本描述
|
||||||
|
|
||||||
|
`ConfigurableListableBeanFactory`接口是Spring框架中的一个关键接口,扩展了`ListableBeanFactory`和`ConfigurableBeanFactory`,提供了更多用于配置和管理bean的方法。通过该接口,可以注册单例对象、自定义作用域、冻结配置、获取BeanDefinition信息、设置父BeanFactory等。
|
||||||
|
|
||||||
|
### 三、主要功能
|
||||||
|
|
||||||
|
1. **注册单例对象**
|
||||||
|
|
||||||
|
+ 允许通过指定的bean名称注册一个单例对象,使用`registerSingleton(String beanName, Object singletonObject)`方法。
|
||||||
|
|
||||||
|
2. **注册作用域**
|
||||||
|
|
||||||
|
+ 提供方法`registerScope(String scopeName, Scope scope)`,用于注册自定义的作用域,扩展了Spring默认的单例、原型等作用域。
|
||||||
|
|
||||||
|
3. **冻结配置**
|
||||||
|
|
||||||
|
+ 通过`freezeConfiguration()`方法,可以冻结bean工厂的配置,防止在后续阶段对其进行修改。这在某些场景下可以增强应用程序的安全性。
|
||||||
|
|
||||||
|
4. **提供已注册的BeanDefinition**
|
||||||
|
|
||||||
|
+ 通过`getBeanDefinition(String beanName)`方法,可以获取指定bean名称的`BeanDefinition`对象,包含有关bean的配置信息,例如作用域、依赖等。
|
||||||
|
|
||||||
|
5. **提供已注册的所有BeanDefinition名称**
|
||||||
|
|
||||||
|
+ 使用`getBeanDefinitionNames()`方法,可以获取所有已注册bean定义的名称数组,方便进行遍历和查看。
|
||||||
|
|
||||||
|
6. **提供已注册的所有单例bean名称**
|
||||||
|
|
||||||
|
+ 通过`getSingletonNames()`方法,可以获取当前已注册的所有单例bean的名称数组,方便查看和管理已实例化的bean。
|
||||||
|
|
||||||
|
7. **设置父BeanFactory**
|
||||||
|
|
||||||
|
+ 允许通过`setParentBeanFactory(BeanFactory parentBeanFactory)`方法设置一个父BeanFactory,使得在父工厂中查找bean定义。
|
||||||
|
|
||||||
|
8. **获取类加载器**
|
||||||
|
|
||||||
|
+ 通过`getBeanClassLoader()`方法获取用于加载bean类的类加载器,这在动态加载类的场景中很有用。
|
||||||
|
|
||||||
|
### 四、接口源码
|
||||||
|
|
||||||
|
```java
|
||||||
|
/**
|
||||||
|
* ConfigurableListableBeanFactory接口是大多数可列举的bean工厂应该实现的配置接口。
|
||||||
|
* 除了继承自{@link ConfigurableBeanFactory}的方法外,它提供了分析和修改bean定义以及预实例化单例bean的功能。
|
||||||
|
*
|
||||||
|
* <p>{@link org.springframework.beans.factory.BeanFactory}的这个子接口通常不应该在正常应用程序代码中使用:
|
||||||
|
* 对于典型的用例,请使用{@link org.springframework.beans.factory.BeanFactory}或
|
||||||
|
* {@link org.springframework.beans.factory.ListableBeanFactory}。
|
||||||
|
* 此接口只是为了允许在需要访问bean工厂配置方法时进行框架内部的插拔。
|
||||||
|
*
|
||||||
|
* @author Juergen Hoeller
|
||||||
|
* @since 03.11.2003
|
||||||
|
* @see org.springframework.context.support.AbstractApplicationContext#getBeanFactory()
|
||||||
|
*/
|
||||||
|
public interface ConfigurableListableBeanFactory
|
||||||
|
extends ListableBeanFactory, AutowireCapableBeanFactory, ConfigurableBeanFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 忽略指定的自动装配依赖类型,例如String。默认为空。
|
||||||
|
* @param type 要忽略的依赖类型
|
||||||
|
*/
|
||||||
|
void ignoreDependencyType(Class<?> type);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 忽略指定的自动装配依赖接口。
|
||||||
|
* <p>通常由应用程序上下文使用,以注册通过其他方式解析的依赖关系,
|
||||||
|
* 例如通过BeanFactoryAware或ApplicationContextAware。
|
||||||
|
* <p>默认情况下,仅忽略BeanFactoryAware接口。
|
||||||
|
* 若要忽略更多类型,请为每个类型调用此方法。
|
||||||
|
* @param ifc 要忽略的依赖接口
|
||||||
|
* @see org.springframework.beans.factory.BeanFactoryAware
|
||||||
|
* @see org.springframework.context.ApplicationContextAware
|
||||||
|
*/
|
||||||
|
void ignoreDependencyInterface(Class<?> ifc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 注册特殊的依赖类型及其对应的自动装配值。
|
||||||
|
* <p>这用于应该是可自动装配但在工厂中未定义为bean的工厂/上下文引用,
|
||||||
|
* 例如类型为ApplicationContext的依赖,解析为bean所在的ApplicationContext实例。
|
||||||
|
* <p>注意:在纯BeanFactory中没有默认类型注册,甚至没有为BeanFactory接口本身注册。
|
||||||
|
* @param dependencyType 要注册的依赖类型。这通常是一个基本接口,如BeanFactory,
|
||||||
|
* 如果声明为自动装配依赖(例如,ListableBeanFactory),则扩展的接口也会被解析,
|
||||||
|
* 只要给定的值实际上实现了扩展接口。
|
||||||
|
* @param autowiredValue 对应的自动装配值。这也可以是org.springframework.beans.factory.ObjectFactory
|
||||||
|
* 接口的实现,允许延迟解析实际目标值。
|
||||||
|
*/
|
||||||
|
void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确定指定的bean是否符合自动装配的条件,
|
||||||
|
* 即是否可注入到声明具有匹配类型的依赖关系的其他bean中。
|
||||||
|
* <p>此方法还检查祖先工厂。
|
||||||
|
* @param beanName 要检查的bean的名称
|
||||||
|
* @param descriptor 要解析的依赖项的描述符
|
||||||
|
* @return bean是否应被视为自动装配候选
|
||||||
|
* @throws NoSuchBeanDefinitionException 如果没有给定名称的bean
|
||||||
|
*/
|
||||||
|
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
|
||||||
|
throws NoSuchBeanDefinitionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回指定bean的注册BeanDefinition,允许访问其属性值和构造函数参数值
|
||||||
|
* (可以在bean工厂后处理期间进行修改)。
|
||||||
|
* <p>返回的BeanDefinition对象不应该是副本,而应该是在工厂中注册的原始定义对象。
|
||||||
|
* 这意味着,如果有必要,它应该可以转换为更具体的实现类型。
|
||||||
|
* <p><b>注意:</b>此方法不考虑祖先工厂。它仅用于访问此工厂的本地bean定义。
|
||||||
|
* @param beanName 要获取的bean的名称
|
||||||
|
* @return 注册的BeanDefinition
|
||||||
|
* @throws NoSuchBeanDefinitionException 如果在此工厂中没有给定名称的bean定义
|
||||||
|
*/
|
||||||
|
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此工厂管理的所有bean名称的统一视图。
|
||||||
|
* <p>包括bean定义名称以及手动注册的单例实例的名称,
|
||||||
|
* bean定义名称始终首先出现,类似于通过类型/注解特定检索bean名称的方式。
|
||||||
|
* @return 用于bean名称视图的复合迭代器
|
||||||
|
* @since 4.1.2
|
||||||
|
* @see #containsBeanDefinition
|
||||||
|
* @see #registerSingleton
|
||||||
|
* @see #getBeanNamesForType
|
||||||
|
* @see #getBeanNamesForAnnotation
|
||||||
|
*/
|
||||||
|
Iterator<String> getBeanNamesIterator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清除合并的bean定义缓存,删除不符合完全元数据缓存资格的bean的条目。
|
||||||
|
* <p>通常在对原始bean定义进行更改后触发,例如在应用BeanFactoryPostProcessor之后。
|
||||||
|
* 请注意,此时已经创建的bean的元数据将被保留。
|
||||||
|
* @since 4.2
|
||||||
|
* @see #getBeanDefinition
|
||||||
|
* @see #getMergedBeanDefinition
|
||||||
|
*/
|
||||||
|
void clearMetadataCache();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 冻结所有bean定义,表示注册的bean定义将不再被修改或进一步后处理。
|
||||||
|
* <p>这允许工厂积极地缓存bean定义元数据。
|
||||||
|
*/
|
||||||
|
void freezeConfiguration();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回此工厂的bean定义是否被冻结,
|
||||||
|
* 即不应再被修改或进一步后处理。
|
||||||
|
* @return 如果工厂的配置被认为已冻结,则为{@code true}
|
||||||
|
*/
|
||||||
|
boolean isConfigurationFrozen();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 确保实例化所有非懒加载单例,还考虑到org.springframework.beans.factory.FactoryBean。
|
||||||
|
* 通常在工厂设置结束时调用,如果需要的话。
|
||||||
|
* @throws BeansException 如果无法创建其中一个单例bean。
|
||||||
|
* 注意:这可能已经使工厂具有一些已初始化的bean!在这种情况下,调用destroySingletons()进行完全清理。
|
||||||
|
* @see #destroySingletons()
|
||||||
|
*/
|
||||||
|
void preInstantiateSingletons() throws BeansException;
|
||||||
|
}
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
### 五、最佳实践
|
||||||
|
|
||||||
|
演示了`ConfigurableListableBeanFactory`接口的一些常用方法。包括依赖类型的忽略、注册可解析的依赖、判断是否为自动注入的候选者、获取BeanDefinition等功能的使用。
|
||||||
|
|
||||||
|
```java
|
||||||
|
public class ConfigurableListableBeanFactoryDemo {
|
||||||
|
|
||||||
|
public static void main(String[] args) throws NoSuchFieldException {
|
||||||
|
// 创建 ApplicationContext
|
||||||
|
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfiguration.class);
|
||||||
|
|
||||||
|
// 获取 ConfigurableListableBeanFactory
|
||||||
|
ConfigurableListableBeanFactory beanFactory = applicationContext.getBeanFactory();
|
||||||
|
|
||||||
|
// 忽略指定类型的依赖
|
||||||
|
beanFactory.ignoreDependencyType(String.class);
|
||||||
|
|
||||||
|
// 忽略指定接口的依赖
|
||||||
|
beanFactory.ignoreDependencyInterface(BeanFactory.class);
|
||||||
|
|
||||||
|
// 注册可解析的依赖
|
||||||
|
beanFactory.registerResolvableDependency(ApplicationContext.class, applicationContext);
|
||||||
|
|
||||||
|
// 判断指定的 Bean 是否可以作为自动注入的候选者
|
||||||
|
String beanName = "myService";
|
||||||
|
|
||||||
|
DependencyDescriptor dependencyDescriptor = new DependencyDescriptor(MyController.class.getDeclaredField("myService"), false);
|
||||||
|
boolean isAutowireCandidate = beanFactory.isAutowireCandidate(beanName, dependencyDescriptor);
|
||||||
|
System.out.println(beanName + " 是否为自动注入的候选者: " + isAutowireCandidate);
|
||||||
|
|
||||||
|
// 获取指定 Bean 的 BeanDefinition
|
||||||
|
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
|
||||||
|
System.out.println(beanName + " 的 BeanDefinition: " + beanDefinition);
|
||||||
|
|
||||||
|
// 获取所有 Bean 的名称的迭代器
|
||||||
|
Iterator<String> beanNamesIterator = beanFactory.getBeanNamesIterator();
|
||||||
|
System.out.print("所有 Bean 的名称: ");
|
||||||
|
beanNamesIterator.forEachRemaining(System.out::print);
|
||||||
|
|
||||||
|
// 清除元数据缓存
|
||||||
|
beanFactory.clearMetadataCache();
|
||||||
|
|
||||||
|
// 冻结配置
|
||||||
|
beanFactory.freezeConfiguration();
|
||||||
|
|
||||||
|
// 判断配置是否已冻结
|
||||||
|
boolean isConfigurationFrozen = beanFactory.isConfigurationFrozen();
|
||||||
|
System.out.println("配置是否已冻结: " + isConfigurationFrozen);
|
||||||
|
|
||||||
|
// 预实例化所有非懒加载的单例 Bean
|
||||||
|
beanFactory.preInstantiateSingletons();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 六、与其他组件的关系
|
||||||
|
|
||||||
|
1. **BeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 继承自 `BeanFactory` 接口,因此它继承了 `BeanFactory` 的基本功能,如 `getBean` 等方法。
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 是 `ListableBeanFactory` 和 `ConfigurableBeanFactory` 的组合,提供了对bean列表和配置的管理能力。
|
||||||
|
|
||||||
|
2. **ListableBeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 扩展了 `ListableBeanFactory` 接口,使得它除了具备 `ListableBeanFactory` 的能力外,还能够进行更灵活的配置和管理。
|
||||||
|
|
||||||
|
3. **AutowireCapableBeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 扩展了 `AutowireCapableBeanFactory` 接口,使得它能够进行更高级的自动装配,包括忽略依赖类型、判断是否为自动注入的候选者等。
|
||||||
|
|
||||||
|
4. **ConfigurableBeanFactory**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 实现了 `ConfigurableBeanFactory` 接口,提供了一系列配置 bean 工厂的方法,如设置 BeanClassLoader、注册单例、设置作用域等。
|
||||||
|
|
||||||
|
5. **ApplicationContext**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 是 Spring 应用上下文(`ApplicationContext`)的一部分。通过 `ApplicationContext` 实例,可以获取到 `ConfigurableListableBeanFactory` 的引用,进而对 bean 进行配置和管理。
|
||||||
|
|
||||||
|
- 具体实现类,例如 `GenericApplicationContext` 或 `AnnotationConfigApplicationContext`,内部持有 `ConfigurableListableBeanFactory` 实例,通过该实例管理 bean 定义和实例。
|
||||||
|
|
||||||
|
6. **BeanPostProcessor**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 与 `BeanPostProcessor` 接口协同工作。`BeanPostProcessor` 允许在 bean 实例化和初始化的过程中进行自定义的处理。`ConfigurableListableBeanFactory` 通过添加 `BeanPostProcessor` 来实现对 bean 的定制化处理。
|
||||||
|
|
||||||
|
7. **BeanDefinition**
|
||||||
|
|
||||||
|
- `ConfigurableListableBeanFactory` 提供了获取 `BeanDefinition` 的方法,通过 `getBeanDefinition(String beanName)` 可以获取指定 bean 的定义信息。这对于查看和修改 bean 的配置信息非常有用。
|
||||||
|
|
||||||
|
### 七、常见问题
|
||||||
|
|
||||||
|
1. **Bean的循环依赖问题**
|
||||||
|
|
||||||
|
- 当两个或多个 bean 彼此依赖形成循环依赖时,可能导致应用程序启动失败或不稳定。我们应该尽量设计避免循环依赖,考虑通过构造函数注入、setter 方法注入、`@Lazy` 注解等方式来解决。
|
||||||
|
|
||||||
|
2. **Bean的配置错误**
|
||||||
|
|
||||||
|
- 配置文件中的 bean 定义存在错误,导致无法正确创建 bean。 我们应该仔细检查配置文件,确保 XML 或 Java 配置正确无误,属性值和引用关系正确。
|
||||||
|
|
||||||
|
3. **依赖注入失败**
|
||||||
|
|
||||||
|
- 依赖注入失败,bean 的某些属性为 null。我们应该检查 bean 的依赖关系,确保属性注入的名称和类型正确,使用 `@Autowired` 或者 `@Resource` 注解时检查自动装配是否生效。
|
||||||
|
|
||||||
|
4. **Bean的生命周期问题**
|
||||||
|
|
||||||
|
- 想要在 bean 的初始化或销毁阶段执行一些特定操作,但操作未生效。我们应该使用 `InitializingBean` 和 `DisposableBean` 接口,或者通过 `@PostConstruct` 和 `@PreDestroy` 注解在方法上执行相应的初始化和销毁逻辑。
|
||||||
|
|
||||||
|
5. **Bean的作用域问题**
|
||||||
|
|
||||||
|
- 需要使用不同的作用域(例如单例、原型等),但实际应用中未生效。我们应该在配置文件或 Java 配置中明确指定 bean 的作用域,确保作用域的使用符合预期。
|
||||||
|
|
||||||
|
6. **Bean的懒加载问题**
|
||||||
|
|
||||||
|
- 想要将某个 bean 设置为懒加载,但该设置未生效。我们应该使用 `@Lazy` 注解或者在 XML 配置中设置 `lazy-init="true"`,确保懒加载的配置正确。
|
||||||
|
|
||||||
|
7. **Bean的条件化注册问题**
|
||||||
|
|
||||||
|
- 想要根据条件动态注册某个 bean,但条件未生效。我们应该使用条件化注解(例如 `@Conditional`)或者通过编程方式在 `ConfigurableListableBeanFactory` 中注册 bean 前进行条件判断。
|
||||||
|
|
||||||
|
8. **Bean的后置处理器问题**
|
||||||
|
|
||||||
|
- 想要对所有 bean 进行额外的处理,但自定义的 `BeanPostProcessor` 未生效。我们应该确保自定义的 `BeanPostProcessor` 被正确注册,可以通过 `ConfigurableListableBeanFactory.addBeanPostProcessor` 方法添加。
|
|
@ -491,3 +491,4 @@ public class MyService {
|
||||||
5. **Bean名称顺序不符合期望**
|
5. **Bean名称顺序不符合期望**
|
||||||
|
|
||||||
- Spring 容器中的 Bean 注册顺序和期望的不一致。对于有顺序要求的情况,可以考虑使用 `@Order` 注解或其他方式指定 Bean 注册顺序。
|
- Spring 容器中的 Bean 注册顺序和期望的不一致。对于有顺序要求的情况,可以考虑使用 `@Order` 注解或其他方式指定 Bean 注册顺序。
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue