Spring IoC之高级特性--创建 Bean后处理器
2014-03-08 12:24
330 查看
有时我们希望在Spring IoC容器中注册自己的插件,在构造期间处理Bean实例。
Bean后处理器允许在初始化回调方法前后进行附加的Bean处理。Bean后处理器的主要特性是逐个处理IoC容器中的所有Bean实例,而不是单个Bean实例。
Bean后处理器的基本要求是实现BeanPostProcessor接口,我们可以实现postProcessAfterInitialization(Object bean, String beanName)和postProcessBeforeInitialization(Object bean, String beanName)方法,在初始化回调方法前后处理所有的Bean。Spring在初始化回调方法前后将Bean实例传给这两个方法,步骤如下:
(1)构造程序或者工厂方法创建Bean实例
(2)为bean属性设置值和Bean引用
(3)调用感知接口中定义的设值方法
(4)将Bean实例传递给每个Bean后处理器中的postProcessBeforeInitialization方法
(5)调用初始化回调方法
(6)将Bean实例传递给每个Bean后处理器中的postProcessAfterInitialization方法
(7)Bean可以使用
(8)容器关闭,调用析构回调方法
使用Bean工厂为IoC容器时,Bean后处理器只能编程注册,更准确是通过addBeanPostProcessor()方法注册。但是,如果使用应用上下文,注册很简单,只要在Bean配置文件中声明一个处理器实例即可。
一、Bean代码
public class EnglishCourse implements Course {
private String name;
private int lessons;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLessons() {
return lessons;
}
public void setLessons(int lessons) {
this.lessons = lessons;
}
}二、客户化Bean后处理器代码
<bean class="com.apress.springrecipes.process.CustomBeanProcess"/>
<bean id="ec" class="com.apress.springrecipes.process.EnglishCourse"/>
如果我们在init-method属性中指定初始化回调方法,或者实现InitializingBean接口,我们的CustomBeanProcess就会很好的工作。
但是,如果EnglishCourse依赖于注解@PostConstruct和@PreDestroy,而且一个CommonAnnotationBeanPostProcessor实例调用初始化方法,那么CustomBeanProcess将不能正常工作。这是因为我们的Bean后处理器的默认优先级低于CommonAnnotationBeanPostProcessor。结果初始化方法将在postProcessBeforeInitialization该方法之前执行。
为了定义Bean后处理器的处理顺序,可以实现它们的Ordered或者PriorityOrdered接口,并在getOrder()方法中返回顺序。这个方法的返回值越低,就代表越高的优先级,PriorityOrdered接口返回的顺序总是优先于Ordered接口的返回值。
因为CommonAnnotationBeanPostProcessor实现了PriorityOrdered接口,所以CustomBeanProcess也必须实现这个接口。
Bean后处理器允许在初始化回调方法前后进行附加的Bean处理。Bean后处理器的主要特性是逐个处理IoC容器中的所有Bean实例,而不是单个Bean实例。
Bean后处理器的基本要求是实现BeanPostProcessor接口,我们可以实现postProcessAfterInitialization(Object bean, String beanName)和postProcessBeforeInitialization(Object bean, String beanName)方法,在初始化回调方法前后处理所有的Bean。Spring在初始化回调方法前后将Bean实例传给这两个方法,步骤如下:
(1)构造程序或者工厂方法创建Bean实例
(2)为bean属性设置值和Bean引用
(3)调用感知接口中定义的设值方法
(4)将Bean实例传递给每个Bean后处理器中的postProcessBeforeInitialization方法
(5)调用初始化回调方法
(6)将Bean实例传递给每个Bean后处理器中的postProcessAfterInitialization方法
(7)Bean可以使用
(8)容器关闭,调用析构回调方法
使用Bean工厂为IoC容器时,Bean后处理器只能编程注册,更准确是通过addBeanPostProcessor()方法注册。但是,如果使用应用上下文,注册很简单,只要在Bean配置文件中声明一个处理器实例即可。
一、Bean代码
public class EnglishCourse implements Course {
private String name;
private int lessons;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getLessons() {
return lessons;
}
public void setLessons(int lessons) {
this.lessons = lessons;
}
}二、客户化Bean后处理器代码
import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class CustomBeanProcess implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化之后执行bean后处理器"); if(bean instanceof EnglishCourse){ EnglishCourse ec = (EnglishCourse)bean; ec.setName("英语教材"); ec.setLessons(45); } return bean; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("初始化之前执行bean后处理器"); return bean; } }三、Bean配置文件
<bean class="com.apress.springrecipes.process.CustomBeanProcess"/>
<bean id="ec" class="com.apress.springrecipes.process.EnglishCourse"/>
如果我们在init-method属性中指定初始化回调方法,或者实现InitializingBean接口,我们的CustomBeanProcess就会很好的工作。
但是,如果EnglishCourse依赖于注解@PostConstruct和@PreDestroy,而且一个CommonAnnotationBeanPostProcessor实例调用初始化方法,那么CustomBeanProcess将不能正常工作。这是因为我们的Bean后处理器的默认优先级低于CommonAnnotationBeanPostProcessor。结果初始化方法将在postProcessBeforeInitialization该方法之前执行。
为了定义Bean后处理器的处理顺序,可以实现它们的Ordered或者PriorityOrdered接口,并在getOrder()方法中返回顺序。这个方法的返回值越低,就代表越高的优先级,PriorityOrdered接口返回的顺序总是优先于Ordered接口的返回值。
因为CommonAnnotationBeanPostProcessor实现了PriorityOrdered接口,所以CustomBeanProcess也必须实现这个接口。
相关文章推荐
- Spring:源码解读(IOC容器的高级特性)
- Spring学习08--IoC容器的高级特性(lazy-init、FactoryBean、BeanPostProcessor、autowiring)
- Spring学习笔记-IOC高级特性2-Spring表达式
- Spring源码学习IOC(6):IoC容器的高级特性
- spring技术内幕6-IoC容器的高级特性
- Spring学习笔记-IOC高级特性3-用Java Config简化XML配置
- spring学习笔记:ioc容器高级特性
- Spring IoC高级特性---Spring自动转化其他非String类型值的问题
- Spring IOC的一些高级特性
- Spring源码解读5——IoC容器的高级特性
- Spring IoC之高级特性--加载外部资源
- Spring学习笔记2——高级特性
- 番外 01:Spring IoC 实现原理简析,Java的反射机制,通过类名创建对象
- 深入研究Spring-IoC :容器创建的几种方式
- 深入研究Spring-IoC:源码分析容器创建
- 《Spring技术内幕》学习笔记6——IoC容器的高级特性
- Spring特性之IOC与DI
- Atitit ioc 之道 attilax著 第2章 装配Bean 33 2.1 Spring配置的可选方案 34 2.2 自动化装配bean 35 2.2.1 创建可被发现的bean 35 2.
- Spring——Web应用中的IoC容器创建(WebApplicationContext根应用上下文的创建过程)
- Spring及Spring的两大特性IOC和AOP