本文转载自spring扩展点整理

背景

Spring的强大和灵活性不用再强调了。而灵活性就是通过一系列的扩展点来实现的,这些扩展点给应用程序提供了参与Spring容器创建的过程,好多定制化的东西都需要扩展点的支持。尤其在使用SpringBoot的过程中。

BeanFactoryPostProcessor

这个扩展点是以一个接口定义的:

/**
* 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;
}

BeanFactoryPostProcessor 这个扩展点的功能是:让应用程序在Spring创建Bean对象前修改BeanDefinition。其中一个例子就是Bean属性配置的类型转换,占位符替换。

BeanDefinitionRegistryPostProcessor

该扩展点的定义如下:

/**
* 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 { true/**
* 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
*/
truevoid postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }

如上面的注释说明:该扩展点可以让应用程序注册自定义的BeanDefinition,并且该扩展点在 BeanFactoryPostProcessor 前执行。

Aware

/**
* Marker superinterface indicating that a bean is eligible to be
* notified by the Spring container of a particular framework object
* through a callback-style method. Actual method signature is
* determined by individual subinterfaces, but should typically
* consist of just one void-returning method that accepts a single
* argument.
*
* <p>Note that merely implementing {@link Aware} provides no default
* functionality. Rather, processing must be done explicitly, for example
* in a {@link org.springframework.beans.factory.config.BeanPostProcessor BeanPostProcessor}.
* Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
* and {@link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory}
* for examples of processing {@code *Aware} interface callbacks.
*
* @author Chris Beams
* @since 3.1
*/
public interface Aware { }

Aware 接口是一个标记接口,表示所有实现该接口的类是会被Spring容器选中,并得到某种通知。所有该接口的子接口提供固定的接收通知的方法。这样的接口有很多,最常用的如下:

public interface ApplicationContextAware extends Aware {
true/**
* Set the ApplicationContext that this object runs in.
* Normally this call will be used to initialize the object.
* <p>Invoked after population of normal bean properties but before an init callback such
* as {@link org.springframework.beans.factory.InitializingBean#afterPropertiesSet()}
* or a custom init-method. Invoked after {@link ResourceLoaderAware#setResourceLoader},
* {@link ApplicationEventPublisherAware#setApplicationEventPublisher} and
* {@link MessageSourceAware}, if applicable.
* @param applicationContext the ApplicationContext object to be used by this object
* @throws ApplicationContextException in case of context initialization errors
* @throws BeansException if thrown by application context methods
* @see org.springframework.beans.factory.BeanInitializationException
*/
truevoid setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}

ApplicationContextAware的回调方法是在一般的属性注入后,但没有执行Bean的初始化方法前被执行的。初始化方法包括init-methodInitializingBeanafterPropertiesSet方法。

/**
* Interface to be implemented by any bean that wishes to be notified
* of the {@link Environment} that it runs in.
*
* @author Chris Beams
* @since 3.1
*/
public interface EnvironmentAware extends Aware {
true/**
* Set the {@code Environment} that this object runs in.
*/
truevoid setEnvironment(Environment environment);
}

该接口用来接收应用程序的运行环境对象。

ApplicationListener

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

true/**
* Handle an application event.
* @param event the event to respond to
*/
truevoid onApplicationEvent(E event); }

ApplicationListener 接口主要用来监听应用程序上下文的事件,不同的实现子类注册自己感兴趣的事件。

InitializingBean

public interface InitializingBean {

true/**
* Invoked by a BeanFactory after it has set all bean properties supplied
* (and satisfied BeanFactoryAware and ApplicationContextAware).
* <p>This method allows the bean instance to perform initialization only
* possible when all bean properties have been set and to throw an
* exception in the event of misconfiguration.
* @throws Exception in the event of misconfiguration (such
* as failure to set an essential property) or if initialization fails.
*/
truevoid afterPropertiesSet() throws Exception; }

InitializingBean 主要用来实现自定义的Bean初始化逻辑。 InitializingBean接口的方法会被BeanFactory在BeanFactoryAware或ApplicationContextAware接口方法调用后进行调用。

InitializingBean 接口的功能还有一个替代方式,就是在xml配置bean结点属性的init-method属性,指定初始化方法。需要注意的时候如同同时实现了InitializingBean接口并且配置了init-method属性,则InitializingBean接口的方法会被先执行。

BeanPostProcessor

public interface BeanPostProcessor {

true/**
* Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
*/
trueObject postProcessBeforeInitialization(Object bean, String beanName) throws BeansException; true/**
* Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
* initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
* or a custom init-method). The bean will already be populated with property values.
* The returned bean instance may be a wrapper around the original.
* <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
* instance and the objects created by the FactoryBean (as of Spring 2.0). The
* post-processor can decide whether to apply to either the FactoryBean or created
* objects or both through corresponding {@code bean instanceof FactoryBean} checks.
* <p>This callback will also be invoked after a short-circuiting triggered by a
* {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
* in contrast to all other BeanPostProcessor callbacks.
* @param bean the new bean instance
* @param beanName the name of the bean
* @return the bean instance to use, either the original or a wrapped one;
* if {@code null}, no subsequent BeanPostProcessors will be invoked
* @throws org.springframework.beans.BeansException in case of errors
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
* @see org.springframework.beans.factory.FactoryBean
*/
trueObject postProcessAfterInitialization(Object bean, String beanName) throws BeansException; }

BeanPostProcessor 接口定义了在bean初始化前和初始化后执行的方法。应用程序自己可以实现该接口定义自己特殊的逻辑。

参考:http://jinnianshilongnian.iteye.com/blog/1489787http://jinnianshilongnian.iteye.com/blog/1492424

FactoryBean

public interface FactoryBean<T> {
T getObject() throws Exception;
Class<?> getObjectType();
boolean isSingleton();
}

通过实现接口FactoryBean来自定义Bean的创建逻辑。Spring容器对待实现了接口FactoryBean的类是特殊处理的。当你需要向容器请求一个真实的FactoryBean实例,而不是它生产的bean,例如调用ApplicationContextgetBean()方法时,在beanid之前要有连字符(&)。对于一个给定 idmyBeanFactoryBean,调用容器的getBean("myBean")方法返回的FactoryBean产品。

spring扩展点整理的更多相关文章

  1. Spring JdbcTemplate用法整理

    Spring JdbcTemplate用法整理: xml: <?xml version="1.0" encoding="UTF-8"?> <b ...

  2. spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情

    <spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...

  3. spring扩展点之二:spring中关于bean初始化、销毁等使用汇总,ApplicationContextAware将ApplicationContext注入

    <spring扩展点之二:spring中关于bean初始化.销毁等使用汇总,ApplicationContextAware将ApplicationContext注入> <spring ...

  4. 2019年Spring核心知识点整理,看看你掌握了多少?

    前言 如今做Java尤其是web几乎是避免不了和Spring打交道了,但是Spring是这样的大而全,新鲜名词不断产生,学起来给人一种凌乱的感觉,在这里总结一下,理顺头绪. Spring 概述 Spr ...

  5. 【JAVA】Spring 数据源配置整理

            在Spring中,不但可以通过JNDI获取应用服务器的数据源,也可以直接在Spring容器中配置数据源,此外,还可以通过代码的方式创建一个数据源,以便进行无依赖的单元测试. 配置数据源 ...

  6. Spring Ioc知识整理

    Ioc知识整理(一): IoC (Inversion of Control) 控制反转. 1.bean的别名 我们每个bean元素都有一个id属性,用于唯一标识实例化的一个类,其实name属性也可用来 ...

  7. [Spring面试] 问题整理

    1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC:Inverse of Control 反转控制的概念,就是将原本在程序中手动创建UserService对象的控制权,交由Spri ...

  8. Spring框架知识整理

    Spring框架主要构成 Spring框架主要有7个模块: 1.Spring AOP:面向切面编程思想,同时也提供了事务管理. 2.Spring ORM:提供了对Hibernate.myBatis的支 ...

  9. 2018/9/6 spring框架的整理

    spring知识的巩固整理AOP和ioc概念,以及了解到了为何要使用spring框架的目的,作用:变换资源获取的方向.更像是按需所求.配置bean的方式:利用XML的方式,基于注解的方式两种.1通过全 ...

随机推荐

  1. Session (简介、、相关方法、流程解析、登录验证)

    Session简介 Session的由来 Cookie虽然在一定程度上解决了"保持状态"的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存在客户端,可能 ...

  2. shell(shell函数、shell正则表达式)

    本章内容 shell函数 shell正则表达式 1.shell函数 linux shell 可以用户定义函数,然后在shell脚本中可以随便调用. 格式: funname () { CMD #函数体 ...

  3. DEDECMS:删除DEDE自带的织梦链方法

    在include/taglib/flinktype.lib.php里删除掉如下代码: $dedecms = false; $dedecms->id = 999; $dedecms->typ ...

  4. ES模块化的导入和导出

    目录 环境准备 模块化 export.import export import import * as export default import 和 require 的区别 参考 环境准备 三个文件 ...

  5. POJ1113:Wall (凸包算法学习)

    题意: 给你一个由n个点构成的多边形城堡(看成二维),按顺序给你n个点,相邻两个点相连. 让你围着这个多边形城堡建一个围墙,城堡任意一点到围墙的距离要求大于等于L,让你求这个围墙的最小周长(看成二维平 ...

  6. poj2001 Shortest Prefixes (trie树)

    Description A prefix of a string is a substring starting at the beginning of the given string. The p ...

  7. Codeforces Round #578 (Div. 2) C. Round Corridor (思维,数论)

    题意: 有一个分两层的圆盘,每层从12点方向均分插入\(n\)和\(m\)个隔板,当内层和外层的隔板相连时是不能通过的,有\(q\)个询问,每次给你内层或外层的两个点,判断是否能从一个点走到另外一个点 ...

  8. 2019-2020 ACM-ICPC Brazil Subregional Programming Contest Problem A Artwork (并查集)

    题意:有一个矩形,有\(k\)个警报器,警报器所在半径\(r\)内不能走,问是否能从左上角走到右下角. 题解:用并查集将所有相交的圆合并,那么不能走的情况如下图所示 所以最后查询判断一下即可. 代码: ...

  9. kubernetes实战-配置中心(三)配置服务使用apollo配置中心

    使用配置中心,需要开发对代码进行调整,将一些配置,通过变量的形式配置到apollo中,服务通过配置中心来获取具体的配置 在配置中心修改新增如下配置: 项目信息: 配置: 重新打包镜像,使用apollo ...

  10. markdown嵌入图片

    这里嵌入指不会因为本地文件丢失而丢失. 参考:https://blog.csdn.net/testcs_dn/article/details/78952358 https://blog.csdn.ne ...