Spring扩展点

目录

BeanDefinition与BeanFactory扩展

BeanDefinitionRegistryPostProcessor接口

BeanFactoryPostProcessor接口

Bean实例化中的扩展

InstantiationAwareBeanPostProcessor接口

SmartInstantiationAwareBeanPostProcessor接口

BeanPostProcessor接口

MergedBeanDefinitionPostProcessor

DestructionAwareBeanPostProcessor

其他扩展点

InitializingBean接口

@PostConstruct注解

各种Aware

BeanDefinition入口扩展

ApplicationListener

ConfigurationClassPostProcessor

CommonAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor

EventListenerMethodProcessor

扩展点在spring中的注入

容器级别

bean级别

总结


注意:本文参考  

Spring有哪些扩展点 - 流浪的雨 - 博客园

BeanDefinition与BeanFactory扩展

spring在生成bean前会先生成bean的定义,然后注册到BeanFactory中,再之后才能生成bean。那么对于从xml配置好的BeanDefinition,如果想要增加删除修改该怎么办呢?

BeanDefinitionRegistryPostProcessor接口

BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor接口随后我们也会讲到。

/**
 * Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for
 * the registration of further bean definitions <i>before</i> regular
 * BeanFactoryPostProcessor detection kicks in. In particular,
 * BeanDefinitionRegistryPostProcessor may register further bean definitions
 * which in turn define BeanFactoryPostProcessor instances.
 *
 * @author Juergen Hoeller
 * @since 3.0.1
 * @see org.springframework.context.annotation.ConfigurationClassPostProcessor
 */
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean definition registry after its
     * standard initialization. All regular bean definitions will have been loaded,
     * but no beans will have been instantiated yet. This allows for adding further
     * bean definitions before the next post-processing phase kicks in.
     * @param registry the bean definition registry used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

这个接口扩展了标准的BeanFactoryPostProcessor 接口,允许在普通的BeanFactoryPostProcessor接口实现类执行之前注册更多的BeanDefinition。特别地是,BeanDefinitionRegistryPostProcessor可以注册BeanFactoryPostProcessor的BeanDefinition。

postProcessBeanDefinitionRegistry方法可以修改在BeanDefinitionRegistry接口实现类中注册的任意BeanDefinition,也可以增加和删除BeanDefinition。原因是这个方法执行前所有常规的BeanDefinition已经被加载到BeanDefinitionRegistry接口实现类中,但还没有bean被实例化。

我们仅仅需要写一个类实现接口,然后将这个类配置到spring的xml配置中。以下是我写的一个简单的实现类:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

public class DefaultBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        logger.info("BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,在这里可以增加修改删除bean的定义");
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        logger.info("BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,在这里可以对beanFactory做一些操作");
    }
}

实际上,Mybatis中org.mybatis.spring.mapper.MapperScannerConfigurer就实现了该方法,在只有接口没有实现类的情况下找到接口方法与sql之间的联系从而生成BeanDefinition并注册。而Spring的org.springframework.context.annotation.ConfigurationClassPostProcessor也是用来将注解@Configuration中的相关生成bean的方法所对应的BeanDefinition进行注册。

BeanFactoryPostProcessor接口

它的执行时机是在Bean定义全部解析及加载完毕【加载完毕指的是bean定义已经被放入到了bean定义注册中心beanDefinitonMap中】,但是在bean实例化之前会被执行

BeanFactory生成后,如果想对BeanFactory进行一些处理,该怎么办呢?BeanFactoryPostProcessor接口就是用来处理BeanFactory的。

/**
 * Allows for custom modification of an application context's bean definitions,
 * adapting the bean property values of the context's underlying bean factory.
 *
 * <p>Application contexts can auto-detect BeanFactoryPostProcessor beans in
 * their bean definitions and apply them before any other beans get created.
 *
 * <p>Useful for custom config files targeted at system administrators that
 * override bean properties configured in the application context.
 *
 * <p>See PropertyResourceConfigurer and its concrete implementations
 * for out-of-the-box solutions that address such configuration needs.
 *
 * <p>A BeanFactoryPostProcessor may interact with and modify bean
 * definitions, but never bean instances. Doing so may cause premature bean
 * instantiation, violating the container and causing unintended side-effects.
 * If bean instance interaction is required, consider implementing
 * {@link BeanPostProcessor} instead.
 *
 * @author Juergen Hoeller
 * @since 06.07.2003
 * @see BeanPostProcessor
 * @see PropertyResourceConfigurer
 */
public interface BeanFactoryPostProcessor {

    /**
     * Modify the application context's internal bean factory after its standard
     * initialization. All bean definitions will have been loaded, but no beans
     * will have been instantiated yet. This allows for overriding or adding
     * properties even to eager-initializing beans.
     * @param beanFactory the bean factory used by the application context
     * @throws org.springframework.beans.BeansException in case of errors
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

这个接口允许自定义修改应用程序上下文的BeanDefinition,调整上下文的BeanFactory的bean属性值。应用程序上下文可以在BeanFactory的BeanDefinition中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。对于定位于系统管理员的自定义配置文件非常有用,它们将覆盖应用程序上下文中配置的bean属性。请参阅PropertyResourceConfigurer及其具体实现,了解解决此类配置需求的开箱即用解决方案。BeanFactoryPostProcessor可能与bean定义交互并修改,但永远不应该将bean实例化。 这样做可能会导致过早的bean实例化,违反容器执行顺序并导致意想不到的副作用。如果需要bean实例交互,请考虑实现BeanPostProcessor接口。

postProcessBeanFactory方法在BeanFactory初始化后,所有的bean定义都被加载,但是没有bean会被实例化时,允许重写或添加属性。

DefaultBeanDefinitionRegistryPostProcessor接口一样,实现并配置到spring的xml配置中即可。

最常用的一个应用就是org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,BeanDefinition生成后,

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值