1.概述

有些时候,我们需要在spring启动过程中加入一些自己的逻辑,特别是一些基本框架和spring做整合的时候(例如:mybatis-spring-boot-starter),就需要使用Spring给我们预留的扩展接口。本文将介绍3个常用的初始化扩展接口:

2.spring初始化

下图是spring启动中,初始化ApplicationContext的3个基本步骤
Spring在初始化每个阶段都提供了一些“Hook”,提供给开发者进行扩展(开闭原则)

3.Hook

3.1 BeanFactoryPostProcessor

public interface BeanFactoryPostProcessor {
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
在ApplicationContext中BeanFactory所有的Bean 的定义已经加载完成,但还未实例化,这个时候可以使用该接口对Bean的属性进行覆盖和设置。

简单的例子:修改Bean的属性

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition myService = beanFactory.getBeanDefinition("myService");
myService.getPropertyValues().add("name", "Lizo");
}
}

使用方法:

在BeanFactory中新增(或修改既有的)BeanDefinition,例如
mockito创建mockBean

3.2 BeanPostProcessor

public interface BeanPostProcessor {
Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}
该接口的作用是在Bean创建对象以后,在bean初始化前后提供回调方法,做一些定制化处理(例如包装成代理对象,bean对象注解处理)。
spring中大量存在BeanPostProcessor的实现类,来完成特定逻辑,下面只是一个简单的例子

简单例子:对@Service注解的Bean,打印当前BeanName

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
} @Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
Service annotation = AnnotationUtils.findAnnotation(bean.getClass(), Service.class);
if (annotation != null) {
System.out.println(beanName);
}
return bean;
}
}

使用方法:

1.Dubbo中远程调用代理类
2.@PostConstruct注解处理

和InitializingBean,@PostConstruct,XxxAware的执行顺序

XxxAware 类似ApplicationContextAware

3.3 ApplicationListener

public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {
void onApplicationEvent(E event);
}
如果是BeanPostProcessor是在Bean初始化前后提供回调,那ApplicationListener就是在ApplicationContext的启动不同阶段提供回调。
根据监听的事件ApplicationEvent来完成回调。常用的事件:
其中可能用的最多的就是ContextRefreshedEvent这个时间。例如有些逻辑要放在整个ApplicationContext完全初始完成之后再执行。

简单例子:ApplicationContext初始完后,把所有BeanPostProcessor实现类设置为null

@Component
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
ApplicationContext applicationContext = event.getApplicationContext();
Map<String, BeanPostProcessor> beansOfType = applicationContext.getBeansOfType(BeanPostProcessor.class);
beansOfType.forEach((k,v)->{
v = null;
});
}
}
 

4.小结

以上3个是Spring中对Bean进行扩展的常用接口,可以通过这些接口新增,修改,代理,校验等逻辑在spring初始化过程中运行。
 
 

如何在Spring框架上做开发之Context启动中的“Hook”的更多相关文章

  1. 如何在spring框架中解决多数据源的问题

    在我们的项目中遇到这样一个问题:我们的项目需要连接多个数据库,而且不同的客户在每次访问中根据需要会去访问不同的数据库.我们以往在spring和hibernate框架中总是配置一个数据源,因而sessi ...

  2. 如何在WebGL全景图上做标记

    WebGL可以用来做3D效果的全景图呈现,例如故宫的全景图.但有时候我们不仅仅只是呈现全景图,还需要增加互动.故宫里边可以又分了很多区域,例如外朝中路.外朝西路.外朝东路等等.我们需要在3D图上做一些 ...

  3. 二十二、【轻量级开源框架】EFW框架Web前端开发之JqueryEasyUI

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...

  4. 二十六、【开源框架】EFW框架Winform前端开发之Grid++Report报表、条形码、Excel导出、图表控件

    回<[开源]EFW框架系列文章索引>        EFW框架源代码下载V1.2:http://pan.baidu.com/s/1hcnuA EFW框架实例源代码下载:http://pan ...

  5. android开发之在activity中控制另一个activity的UI更新

    转自:http://blog.csdn.net/jason0539/article/details/18075293 第一种方法: 遇到一个问题,需要在一个activity中控制另一个acitivit ...

  6. Lotus开发之Lotus Notes中域的验证

    一:介绍       Lotus中的域主要有以下的类型:文本,日期/时间,对话框列表,复选框,单选按钮,RTF等等.Lotus中域的验证方式有很多种公式,lotusscript,javascript等 ...

  7. iOS开发之App启动原理

    iOS程序的启动过程 程序启动的完整过程大致步骤如下: 1.main函数 2.UIApplicationMain * 创建UIApplication对象 * 创建UIApplication的deleg ...

  8. 游戏开发之在UE4中编写C++代码控制角色

    当你运行我们上次做完的项目,你可能会意识到我们移动的摄像机还是默认的那个摄像机,这个默认的摄像机可以自由飞翔.这一节,我们要使得开始的角色是我们的一个Avatar类的实例对象,并且使用键盘控制我们的角 ...

  9. 嵌入式Linux开发之uboot启动Linux整体流程分析

    嵌入式Linux开发之uboot启动Linux整体流程分析 Uboot全称Universal Boot Loader,一个遵循GPL协议的的开源项目,其作用是引导操作系统,支持引导linux.VxWo ...

随机推荐

  1. google开源服务器apprtc的搭建

    本文参考网帖: http://www.jianshu.com/p/c55ecf5a3fcf http://io.diveinedu.com/2015/02/05/%E7%AC%AC%E5%85%AD% ...

  2. VSCode配置eslint

    在Vue.js项目中,使用的是eslint检查. 而在我写完代码后,cnpm run dev运行命令...然后悲剧了,一大堆报错!╮(╯▽╰)╭ 安装插件:Vetur:这是vscode上一个vue.j ...

  3. js二级事件模型的处理细节

    一.纠正网络上的一个误传--“IE不支持事件捕获” 可以在浏览器中运行上面demo,在各主流浏览器中,鼠标移上都可以分别触发捕获与冒泡事件的监听函数,所以IE也是支持事件捕获的,连IE6都支持,只是在 ...

  4. Azure ARM (18) 将传统的ASM VM迁移到ARM VM (1)

    <Windows Azure Platform 系列文章目录> 目前很多客户陆续的把传统ASM VM迁移至ARM VM.我这里简单介绍一下. 整个迁移过程分为: 1.Validate,Az ...

  5. Vue深度学习(2)

    Text 可以在表单的input 元素上使用v-model 指令来创建双向数据绑定.它会根据input元素的类型自动选取正确的绑定模式. <div id="app"> ...

  6. 四、Spring Boot 多数据源 自动切换

    实现案例场景: 某系统除了需要从自己的主要数据库上读取和管理数据外,还有一部分业务涉及到其他多个数据库,要求可以在任何方法上可以灵活指定具体要操作的数据库.为了在开发中以最简单的方法使用,本文基于注解 ...

  7. web项目启动流程探索

    在web项目的启动过程中,我们希望知道它的一般流程是什么,这样我们就可以在各个流程中加入相应的功能,或者对于我们排错也有帮助. 我们知道,当我们启动tomcat容器以后,容器首先初始化一些必要的组件, ...

  8. redis的sorted set类型

    1.简单描述 和set类型一样,sorted set也是string类型元素的集合,不同的是每个元素都会关联一个double类型的score.sorted set的实现是skip list和hash ...

  9. myeclipse 2014 customize_Perspective 失效解决方法-有效

    1.将9个jar复制到myeclipse安装目录\plugins中 2.删除和这9个jar同包名但是版本号较低的9个文件 3.重启myeclipse 2014 三步走: 到这个地址下载 http:// ...

  10. 安装eclipse时跳转到网页提示JRE Missing

    可能的原因:jdk与安装的eclipse不兼容,可能64位机器安装了32位的jdk,导致64位的eclipse不能识别.