springboot提供的扩展接口

BeanPostProcess接口

在每个bean初始化成前后做操作。

如果想在系统中的所有(或者部分bean)初始化前后,做些事情,可继承该接口,使用方式如下图示例:

springboot提供的扩展接口

就这样,在每个实例初始化前后,将会执行相关打印。

 

InstantiationAwareBeanPostProcessor接口

在Bean实例化前后做一些操作。

该接口继承了BeanPostProcess接口,并在此的基础上又增加了3个方法,增加了扩展bean的功能。

springboot提供的扩展接口

可以看到,需要实现 5 个方法,其中2个方法是 BeanPostProcess 接口定义的方法:在bean初始化的前后执行,而 InstantiationAwareBeanPostProcessor 则新增了 3 个方法,分别是 postProcessBeforeInstantiation (实例化之前),postProcessAfterInstantiation (实例化之后),postProcessPropertyValues (在处理Bean属性之前),开发者可以在这三个方法中添加自定义逻辑。执行顺序为:先实例化,在初始化。即postProcessBeforeInstantiation->postProcessAfterInstantiation->postProcessPropertyValues->postProcessBeforeInitialization->@PostConstruct注解修饰的方法(如果有的话)->postProcessAfterInitialization。

 

BeanNameAware、ApplicationContextAware 和 BeanFactoryAware接口

针对bean工厂,可以获取上下文,可以获取当前bean的id。这三个接口都继承自 Aware 接口,并分别定义了自己的接口定义方法。实现这些接口就能得到Spring的Bean 工厂、以及应用上下文等信息。从而调用getBean方法获取Bean。很多项目中都使用此接口做为Spring的工具类。比如可以像这么使用:

springboot提供的扩展接口

 

BeanFactoryPostProcessor接口

Spring允许在Bean创建之前,读取Bean的元属性,并根据自己的需求对元属性进行改变

所有的bean定义都已经加载了,但是还没有实例化bean。这允许覆盖或添加属性,甚至是对初始化bean的属性。参数是什么呢?应用程序上下文所使用的bean工厂。也就是说,我们可以获取某个Bean的定义,然后修改该Bean的定义:比如下面这样:

springboot提供的扩展接口

 

InitialingBean、DisposableBean接口

InitialingBean 在属性设置完毕后做一些自定义操作。 DisposableBean 在关闭容器前做一些操作。

springboot提供的扩展接口

执行顺序为:setName、init、afterPropertiesSet,如果和前面的TAInstantiationAwareBeanPostProcessor结合起来,则顺序为:

  1. 实例化前postProcessBeforeInstantiation
  2. 实例化后postProcessAfterInstantiation
  3. 处理属性前postProcessPropertyValues
  4. 处理属性setName
  5. 初始化前postProcessBeforeInitialization
  6. @PostConstruct修饰的方法
  7. 属性设置完毕afterPropertiesSet
  8. 初始化后postProcessAfterInitialization

 

ApplicationListener事件和事件监听

假设在用户注册成功后,需要向用户发送邮件时,也可以使用springboot的事件监听,详情可参考另外一篇博文springboot生命周期和监听器。代码如下:

springboot提供的扩展接口

 

ApplicationContextInitializer接口

应用初始化器,在ApplicationContext做refresh之前(prepareContext时),允许我们对ApplicationContext的实例做进一步的设置或者处理。详情可参考另外一篇博文springboot应用上下文初始化器。最近在项目中有这么个需求,项目在重构时,需要对某个包下的大多数类的大多数方法进行验证,即在进入这些类的这些方法时,执行一个验证,如果验证不通过则抛出异常。解决方案是在项目中使用javassist动态字节码技术实现AOP前置操作,但如何将这个验证的AOP代码在springboot启动时(在bean加载前)引入spring呢,就是通过自定义initializer实现的。

springboot提供的扩展接口

一个系统中可以有多个自定义初始化器,在配置文件中以逗号分隔。

初始化器结合监听器使用实例:

springboot提供的扩展接口

 

FactoryBean接口

FactoryBean可以用来创建一个复杂的bean对象。一般通过component、service等创建的bean都是一些简单的bean,而比较复杂的bean可以使用FactoryBean来创建。

注意:FactoryBean和BeanFactory的区别。

FactoryBean:是一个创建bean的工厂接口,用来创建bean。

BeanFactory:是一个存储和管理bean的容器。

假设要注入一个名叫applicationEventMulticaster的bean,并设置其任务调度器为线程池,具体代码如下:

springboot提供的扩展接口

这样,就相当于想spring容器注入了一个bean,其名字为applicationEventMulticaster,类型为getObjectType返回的类型,并且是单例。

但springboot有种更好的方式来实现同样的功能,具体见如下代码:

springboot提供的扩展接口

在一个被@Configuration修饰的类中,通过@Bean修饰一个方法,方法的返回类型为要注入类的类型。这样也能对spring注入了一个叫applicationEventMulticaster的bean,其类型为SimpleApplicationEventMulticaster。