浅析Spring IoC源码(四)分析BeanPostProcessor(1)
2016-11-28 09:57
906 查看
这个接口的注释中原作者说明了该接口的作用:
“工厂钩子允许用户自定义修改创建的bean实例,应用上下文可以在ben的定义中自动检测beanPostProecessor,并且将其应用于随后创建的任意bean中,并且可以通过factory给其他的类进行注册然后使用”
说白了,就是我们可以自定义的去修改spring给我们创建的类,给了我们一个二次修改bean的机会,这种设计思路与spring的“开闭原则”相符合,没有过度分装,举例来说,我们根据beanDefinition去查找一个Teacher,找到之后spring给我们实例化这个Teacher,但是我们用这个teacher的时候,发现这个teacher会抽烟,我们可以修改这个老师会抽烟的属性,这样就得到了一个完美的老师,这个完美的老师授课结束后,我们再告诉他你可以接着抽烟了,所以spring给我们想的还是很周到的~
再看这个接口定义的2个方法
BeanPostProcessor这个接口就2个方法,根据这2个方法的名称,我们就大概知道这2个方法的做什么的了
postProcessBeforeInitialization在“初始化之前处理”
postProcessAfterInitialization在“初始化之后处理”
废话不多说,我们就实现一个上面讲述的例子,大家更加深入的理解一下BeanPostProcessor这个作用
Teacher.Java
[java] view
plain copy
package org.study.spring.beanpostprocessor.demo;
public class Teacher {
/**
* 老师的姓名
*/
private String name;
/**
* 年龄
*/
private int age;
/**
* 是否抽烟
*/
private boolean smoking;
/**
* 老师教授的课程
*/
private String language;
/**
* 临时变量,默认抽烟
*/
private boolean tempSmoking = true;
public Teacher() {
}
public boolean isTempSmoking() {
return tempSmoking;
}
public void setTempSmoking(boolean tempSmoking) {
this.tempSmoking = tempSmoking;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public boolean isSmoking() {
return smoking;
}
public void setSmoking(boolean smoking) {
this.smoking = smoking;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public void teach(){
System.out.println("I am :"+name+" and I will teach you :"+language + " and I "+(tempSmoking?"will":"will not")+" smoking");
}
}
ChangeTeacherSmokingBeanPostProcessor.java
[java] view
plain copy
package org.study.spring.beanpostprocessor.demo;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class ChangeTeacherSmokingBeanPostProcessor implements BeanPostProcessor{
/**
* 初始化之前处理
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException {
/**
* 只处理该bean的类型是Teacher的
*/
if(bean instanceof Teacher){
Teacher teacher = (Teacher)bean;
/**
* 实例化之前,要吧所有抽烟的都改成不抽烟的
*/
if(teacher.isSmoking()){
((Teacher)bean).setTempSmoking(false);
}
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
return bean;
}
}
bean-post-processor-teacher.xml
[html] view
plain copy
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd">
<bean id="teacher" class="org.study.spring.beanpostprocessor.demo.Teacher">
<property name="name" value="孔浩"/>
<property name="age" value="32"/>
<property name="smoking" value="true"/>
<property name="language" value="java"/>
</bean>
<bean id="changeTeacher" class="org.study.spring.beanpostprocessor.demo.ChangeTeacherSmokingBeanPostProcessor"/>
</beans>
ChangeTeacherSmokingBeanPostProcessorTest.java
[java] view
plain copy
package org.study.spring.beanpostprocessor.demo;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ChangeTeacherSmokingBeanPostProcessorTest{
@Test
public void test2() throws Exception{
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-post-processor-teacher.xml");
Teacher teacher = applicationContext.getBean("teacher",Teacher.class);
teacher.teach();
}
}
运行结果
上面的例子只是说明,spring在初始化之前,给了我们开发者二次修改的机会,beanPostProcessor这个类是“spring”开闭原则的典型实现,下一节详细讲述它在项目中的具体运用~
相关文章推荐
- 做一个合格的程序猿之浅析Spring IoC源码(四)分析BeanPostProcessor(1)
- 【spring源码分析】BeanDefinitionRegistryPostProcessor接口可自定义bean加入IOC
- 做一个合格的程序猿之浅析Spring IoC源码(六)BeanFactoryPostProcessor
- spring 源码分析之BeanPostProcessor
- Spring源码分析之BeanPostProcessor接口和BeanFactoryPostProcessor接口方法不执行原因分析
- Spring源码分析之BeanPostProcessor接口和BeanFactoryPostProcessor接口方法不执行原因分析
- Ioc容器BeanPostProcessor-Spring 源码(3)
- Spring源代码分析(4)---BeanFactoryPostProcessor(看见的不一定是真的)
- Spring 源码梳理(二) BeanPostProcessor
- spring源码:BeanPostProcessor(li)
- 浅析Spring IoC源码(十)Spring Bean的初始化顺序
- 浅析Spring IoC源码(五)再谈BeanPostProcessor(2)
- Spring源码分析1--IoC容器载入Bean定义资源
- (spring-第9回【IoC基础篇】)BeanFactoryPostProcessor,实例化Bean之前的第二大利器
- Spring源码之ApplicationContext(六)注册BeanPostProcessor
- 浅析Spring AOP源码(十四) 分析ProxyFactoryBean
- 做一个合格的程序猿之浅析Spring IoC源码(二)BeanFactory初始化
- 做一个合格的程序猿之浅析Spring IoC源码(十)Spring Bean的初始化顺序
- 做一个合格的程序猿之浅析Spring IoC源码(七)浅谈BeanFactory和FactoryBean
- 做一个合格的程序猿之浅析Spring IoC源码(八)了解BeanFactoryAware