环境:Spring5.3.10
BeanFactory
BeanFactoryAPI为Spring的IoC功能提供了基础。它的特定契约主要用于与Spring和相关第三方框架的其他部分集成,其DefaultListableBeanFactory实现是更高级别的GenericaApplicationContext容器中的一个关键委托。
BeanFactory和相关接口(如BeanFactoryAware、InitializingBean、DisposableBean)是其他框架组件的重要集成点。不需要任何注释或者反射,它们允许容器及其组件之间进行非常有效的交互。应用程序级bean可以使用相同的回调接口,但通常更喜欢通过注释或编程配置进行声明性依赖项注入。
请注意,核心BeanFactory API级别及其DefaultListableBeanFactory实现不对要使用的配置设计或任何组件注释进行承担。所有这些风格都是通过扩展(如XmlBeanDefinitionReader和AutowiredNotationBeanPostProcessor)引入的,并作为核心元数据表示在共享BeanDefinition对象上操作。这就是Spring容器如此灵活和可扩展的本质所在。简单说就是核心的BeanFactory API不做配置或者是注解进行处理,这些处理都是通过扩展实现(如:BeanPostProcessor来实现AOP)。
BeanFactory or ApplicationContext 差异
除非有充分的理由,否则应该使用ApplicationContext,将GenericaApplicationContext及其子类AnnotationConfigApplicationContext作为自定义启动容器的常见实现。这些是Spring核心容器的主要入口点,用于所有常见目的:加载配置文件、触发类路径扫描、以编程方式注册bean定义和注释类,以及(从5.0开始)注册函数bean定义。
由于ApplicationContext包含BeanFactory的所有功能,因此通常建议不要使用普通BeanFactory,除非需要完全控制bean处理。在ApplicationContext(如GenericaApplicationContext实现)中,通过约定(即,通过bean名称或bean类型)检测几种bean?—?特别是后处理器),而普通的DefaultListableBeanFactory对任何特殊bean都是不可知的。
对于许多扩展容器特性,例如注释处理和AOP代理,BeanPostProcessor扩展点是必不可少的。如果只使用普通的DefaultListableBeanFactory,则默认情况下不会检测和激活此类后处理器。这种情况可能令人困惑,因为您的bean配置实际上没有任何问题。相反,在这种情况下,需要通过额外的设置来完全配置启动容器。简单说如果你使用DefaultListableBeanFactory那么你的注解处理和AOP都将不会生效,除非自己去设置这些BeanPostProcessor。
下表列出了BeanFactory和ApplicationContext接口和实现提供的功能。
功能 | BeanFactory | ApplicationContext |
Bean实例化 | Yes | Yes |
生命周期管理 | No | Yes |
自动注册BeanPostProcessor | No | Yes |
自动注册BeanFactoryPostProcessor | No | Yes |
方便的消息源访问(用于国际化) | No | Yes |
内置ApplicationEvent发布机制 | No | Yes |
手动注册
如要应用BeanPostProcessor则需要编程的方式注册。
要向DefaultListableBeanFactory显式注册bean后处理器,需要以编程方式调用addBeanPostProcessor,如下例所示:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// populate the factory with bean definitions
// 注册需要的BeanPostProcessor实例
factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
factory.addBeanPostProcessor(new MyBeanPostProcessor());
// 现在可以启动factory容器了
要将BeanFactory后处理器应用于普通DefaultListableBeanFactory,需要调用其后处理BeanFactory方法,如下例所示:
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
// 从属性文件中引入一些属性值
PropertySourcesPlaceholderConfigurer cfg = new PropertySourcesPlaceholderConfigurer();
cfg.setLocation(new FileSystemResource("jdbc.properties"));
cfg.postProcessBeanFactory(factory);
在这两种情况下,显式注册步骤都不方便,这就是为什么在Spring支持的应用程序中,各种ApplicationContext变体比普通的DefaultListableBeanFactory更受欢迎的原因,特别是在典型的企业设置中,依赖BeanFactoryPostProcessor和BeanPostProcessor实例实现扩展容器功能时。
完毕!!!
求个关注
公众:Springboot实战案例锦集