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. 【new File(String Path)加载资源问题】

    2017-12-17   15:07:38  [原创-wx] 一.我们在用IO流加载资源的时候,创建文件资源 1 File file = New File("String Path" ...

  2. 》》HTML5 移动页面自适应手机屏幕四类方法

    1.使用meta标签:viewport H5移动端页面自适应普遍使用的方法,理论上讲使用这个标签是可以适应所有尺寸的屏幕的,但是各设备对该标签的解释方式及支持程度不同造成了不能兼容所有浏览器或系统. ...

  3. Struts2.5 伪静态的配置

    伪静态 伪静态是相对真实静态来讲的,通常我们为了增强搜索引擎的友好面,都将文章内容生成静态页面,但是有的朋友为了实时的显示一些信息.或者还想运用动态脚本解决一些问题.不能用静态的方式来展示网站内容.但 ...

  4. 自学Python2.2-基本数据类型-列表list(object)

    Python List方法总结 一. 列表简介: 列表是序列对象,可包含任意的Python数据信息,如字符串.数字.列表.元组等   列表的数据是可变的,我们可通过对象方法对列表中的数据进行增加.修改 ...

  5. JPA(API)

    1. Persistence EntityManagerFactory 2. EntityManager#find EntityManager#getReference EntityManager#p ...

  6. 配置java项目的intellij idea的运行环境

    才疏学浅,只懂一点点前端的皮毛东西,对于项目运行环境的配置一无所知,今天简单记录一下! 前提:装好了jdk.maven.intellij idea. 1. file菜单->Open...打开从S ...

  7. 瞎j8封装第二版之用xml文件来代理dao接口

    也是重新整理了之前的那篇 模仿Mybatis用map per.xml实现Dao层接口的功能 话不多说直接上代码 首先是结构 依赖pom.xml <?xml version="1.0&q ...

  8. Docker容器中开始.NETCore之路

    一.引言 开始写这篇博客前,已经尝试练习过好多次Docker环境安装,.Net Core环境安装了,在这里替腾讯云做一个推广,假如我们想学习.练手.net core 或是Docker却苦于没有开发环境 ...

  9. Beautiful Paintings

    There are n pictures delivered for the new exhibition. The i-th painting has beauty ai. We know that ...

  10. BZOJ4970 IOI2004 empodia障碍段

    4970: [ioi2004]empodia 障碍段 Time Limit: 10 Sec  Memory Limit: 128 MB Description 古数学及哲学家毕氏相信自然之本质为数学. ...