深入理解spring容器扩展点BeanFactoryPostProcessor

在这里插入图片描述

spring官网是这样描述BeanFactoryPostProcessor的:

  1. BeanFactoryPostProcessor可以对Bean配置元数据进行操作,也就是说,spring容器允许BeanFactoryPostProcessor读取指定Bean的配置元数据,并可以在Bean被实例化前修改它,这个的配置元数据就是BeanDefination
  2. 我们可以配置多个BeanFactoryPostProcessor,并且只要我们配置的BeanFactoryPostProcessor实现了Ordered接口的话,我么还可以控制这些BeanFactoryPostProcessor的执行顺序。

eg:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="locations" value="classpath:com/something/jdbc.properties"/>
</bean>

<bean id="dataSource" destroy-method="close"
        class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
# jdbc.properties
jdbc.driverClassName=org.hsqldb.jdbcDriver
jdbc.url=jdbc:hsqldb:hsql://production:9002
jdbc.username=sa
jdbc.password=root

在这里插入图片描述

  • Ordered用于决定执行顺序;
  • PriorityOrdered这个接口直接继承Ordered接口,并且没有做任何扩展,只是作为一个标记接口,也用于决定BeanFactoryPortProcessor的执行顺序。
  • Aware
  • FunctionalInterface这是java8新增的一个接口,也是一个标记接口,标记该接口是一个函数式接口;
  • BeanFactoryPortProcessor代表这个类是一个Bean工厂的后置处理器;
  • PropertiesLoaderSupport这个类主要包含定义了属性的加载方法,包含属性如下:
// 本地属性,可以直接在XML中配置

@Nullable

protected Properties[] localProperties;


// 是否用本地的属性覆盖提供的文件中的属性,默认不会

protected boolean localOverride = false;


// 根据地址找到的对应文件

@Nullable

private Resource[] locations;


// 没有找到对应文件是否抛出异常,false代表不抛出

private boolean ignoreResourceNotFound = false;


// 对应文件资源的编码

@Nullable

private String fileEncoding;


// 文件解析器

private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
  • PropertyResourceConfigurer这个类主要可以对读取到的属性进行一些转换;
  • PlaceholderConfigurerSupport主要负责对占位符进行解析,其中属性如下:
// 默认解析的前缀

public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

// 默认解析的后缀

public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

// 属性名称跟属性值的分隔符

public static final String DEFAULT_VALUE_SEPARATOR = ":";
  • PropertyPlaceholderConfigurer继承上面这些类的所有功能,同时可以配置属性的解析顺序;
// 不在系统属性中查找

public static final int SYSTEM_PROPERTIES_MODE_NEVER = 0;


// 如果在配置文件中没有找到,再去系统属性中查找

public static final int SYSTEM_PROPERTIES_MODE_FALLBACK = 1;


// 先查找系统属性,没查到再去查找配置文件中的属性

public static final int SYSTEM_PROPERTIES_MODE_OVERRIDE = 2;

如何将jdbc.properties文件中的属性值应用到BasicDtaSource这个Bean上

在这里插入图片描述PropertyPlaceholdConfigurer这个特殊的BeanFactoryPostProcessor完成了BeanDefinition中的属性值中的占位符的替换,BeanDefinition被解析出来后,bean实例化之前对其进行了更改。

spring是如何扫描并解析成BeanDefinition的?

BeanDefinitionRegistryPostProcessor

在这里插入图片描述

  1. 直接继承BeanFactoryPostProcessor,所以是一个Bean工厂后置处理器;
  2. 实现类ConfigurationClassPostProcessor,扫描解析Bean就是由这个类完成的;
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

public interface BeanFactoryPostProcessor {
	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

相比于正常的BeanFactoryPostProcessorBeanDefinitionRegistryPostProcessor多提供了一个方法,这个方法相比于父类的postProcessBeanFactory方法更加靠前执行,所以spring利用这个特性来完成扫描。

执行流程源码解析

在这里插入图片描述
BeanDefinitionRegistryPostProcessor执行流程

在这里插入图片描述

在使用postProcessBeanFactory这个方法时,所有的BeanDefinition都已经被加载,而postProcessBeanDefinitionRegistry允许我们在下一个后置处理器执行前添加更多的BeanDefinition
,所以后者的执行时机早于前者;

总结如下:

  • 先执行直接实现了BeanDefinitionRegistryPostProcessor接口的后置处理器,所有实现了BeanDefinitionRegistryPostProcessor接口的类有两个方法,一个是特有的postProcessBeanDefinitionRegistry方法,一个是继承子父接口的postProcessBeanFactory方法。
    • postProcessBeanDefinitionRegistry方法早于postProcessBeanFactory方法执行,对于postProcessBeanDefinitionRegistry的执行顺序又遵循如下原子

      • ⅰ. 先执行实现了PriorityOrdered接口的类中的postProcessBeanDefinitionRegistry方法
      • ⅱ. 再执行实现了Ordered接口的类中的postProcessBeanDefinitionRegistry的方法
      • ⅲ. 最后执行没有实现上面两个接口的类中的postProcessBeanDefinitionRegistry的方法
    • 执行完所有的postProcessBeanDefinitionRegistry方法后,再执行实现了BeanDefinitionRegistryPostProcessor接口的类中的postProcessBeanFactory方法

  • 再执行直接实现了BeanFactoryPostProcessor接口的后置处理器
    a. 先执行实现了PriorityOrdered接口的类中的postProcessBeanFactory方法
    b. 再执行实现了Ordered接口的类中的postProcessBeanFactory的方法
    c. 最后执行没有实现上面两个接口的类中的postProcessBeanFactory的方法.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个非常强大的IoC容器和框架,提供了许多的扩展,可以让开发人员在不修改Spring源码的情况下,为应用程序添加自定义的行为和功能。以下是Spring的一些常见扩展: 1. BeanPostProcessor:这是Spring中最重要的扩展之一。BeanPostProcessor可以在Bean实例化、属性注入、初始化和销毁时对Bean进行前置或后置处理。通过实现BeanPostProcessor接口,可以在Bean实例化和初始化的过程中,对Bean进行修改、增强或者验证等操作。 2. BeanFactoryPostProcessorBeanFactoryPostProcessor是在BeanFactory标准初始化之后调用的,在Bean实例化之前对BeanFactory进行修改。通过实现BeanFactoryPostProcessor接口,可以在容器启动之后,动态修改BeanFactory中的Bean定义信息,如修改Bean的属性值、修改Bean的作用域、添加新的BeanDefinition等。 3. ApplicationListener:Spring提供了事件机制,通过实现ApplicationListener接口,可以监听容器中发生的事件,如容器启动、关闭、Bean初始化等。当事件发生时,容器会调用实现ApplicationListener接口的Bean的onApplicationEvent方法,从而实现自定义的行为。 4. InitializingBean和DisposableBean:这两个接口可用于在Bean实例化和销毁时执行一些特定的操作,如资源的获取和释放等。当Bean实现了这两个接口时,在容器初始化和销毁时,容器会自动调用Bean的afterPropertiesSet和destroy方法。 5. FactoryBean:FactoryBean是一个接口,它允许Bean实例化的过程由用户自定义。FactoryBean可以创建一个特定类型的Bean或者返回不同的Bean实例,从而实现更加灵活的Bean实例化方式。 6. AOP扩展Spring的AOP框架为开发人员提供了许多扩展,例如Advice、Pointcut、Advisor和Interceptor等,可以实现拦截器、增强器、切面等功能,为应用程序添加自定义的行为和功能。 总的来说,Spring提供了许多扩展,可以让开发人员在应用程序中添加自定义的行为和功能,从而更好地满足业务需求。这些扩展包括BeanPostProcessorBeanFactoryPostProcessor、ApplicationListener、InitializingBean和DisposableBean、FactoryBean和AOP扩展等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值