首页 > 编程语言 > 详细

深入了解Spring

时间:2017-02-04 20:18:47      阅读:319      评论:0      收藏:0      [点我收藏+]

1.Bean后处理器

Spring容器提供了一个接口InitializingBean,实现这个接口的bean只要重写afterPropertiesSet()或者在XML中添加init-method属性,就可以在Bean初始化前后执行特定行为。

InitializingBean是针对单个Bean起作用的,Spring还提供了另外一个接口叫BeanPostProcessor,这个接口是针对容器中所有Bean起作用的。

只要定义个普通的Bean实现这个接口,并实现postProcessBeforeInitialization()和postProcessAfterInitialization()两个方法,容器中所有的Bean都会受影响。

下面是一个实现了BeanPostProcessor的普通bean类,

 1 package spi;
 2 
 3 import org.springframework.beans.BeansException;
 4 import org.springframework.beans.factory.config.BeanPostProcessor;
 5 
 6 public class MyBeanPostProcessor implements BeanPostProcessor {
 7 
 8     @Override
 9     public Object postProcessBeforeInitialization(Object bean, String beanName)
10             throws BeansException {
11         System.out.println("Bean后处理器在初始化之前对 "+beanName+" 进行增强处理...");
12         return bean;
13     }
14 
15     @Override
16     public Object postProcessAfterInitialization(Object bean, String beanName)
17             throws BeansException {
18         System.out.println("Bean后处理器在初始化之后对 "+beanName+" 进行增强处理...");
19         if (bean instanceof Chinese) {
20             System.out.println("Bean后处理器将Chinese.beanName修改为‘Java编程‘.");
21             Chinese c = (Chinese)bean;
22             c.setBeanName("Java编程");
23         }
24         return bean;
25     }
26     
27 }

特意让这个bean修改chinese这个bean的属性,下面是chinese Bean的代码,

 1 package spi;
 2 
 3 import org.springframework.beans.factory.BeanNameAware;
 4 import org.springframework.beans.factory.InitializingBean;
 5 
 6 public class Chinese implements Person, InitializingBean {
 7     private Son son;
 8     private String beanName;
 9 
10     public void setBeanName(String beanName) {
11         System.out.println(beanName+":Spring正在执行setBeanName()方法注入依赖关系...");
12         this.beanName = beanName;
13         
14     }
15     public void info(){
16         System.out.println("我在XML中的id名称为:"+beanName);
17     }
18     public int age;
19     private Axe axe;
20     public int getAge() {
21         return age;
22     }
23     public void setAge(int age) {
24         this.age = age;
25     }
26     public Axe getAxe() {
27         return axe;
28     }
29     public void setAxe(Axe axe) {
30         this.axe = axe;
31     }
32     public Chinese() {
33         System.out.println("Spring正在执行默认构造函数构造Chinese实例...");
34     }
35     public Chinese(Axe axe) {
36         this.axe = axe;
37     }
38     public void useAxe() {
39         System.out.println("我打算去砍点柴火");
40         System.out.println("修改beanName="+beanName+","+axe.chop());
41     }
42     public void close() {
43         System.out.println("正在执行销毁前的方法 close ...");
44     }
45     public Son getSon() {
46         return son;
47     }
48     public void setSon(Son son) {
49         this.son = son;
50     }
51     public void init() {
52         System.out.println("正在执行初始化方法init...");
53     }
54     @Override
55     public void afterPropertiesSet() throws Exception {
56         // TODO Auto-generated method stub
57         System.out.println("正在执行初始化方法afterPropertiesSet...");
58     }
59 
60 }

Chinese Bean实现了InitializingBean接口,添加了init()(需要XML配置)方法和afterPropertiesSet()方法,那么它在初始化前后会被插入特定行为,行为由这两个方法决定。 同时,由于容器中存在实现了BeanPostProcessor的Bean,那么所有Bean包括chinese,都会在初始化前后批量被插入特定行为。

XML配置如下,

1     <bean id="chinese" class="spi.Chinese" 
2     init-method="init" p:axe-ref="steelAxe" p:beanName="依赖注入的值" />
3     <bean class="spi.MyBeanPostProcessor" />

测试代码,

1     public static void test8() {
2         ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
3         Person p = ctx.getBean("chinese", Person.class);
4         p.useAxe();
5     }

 

执行结果,

 1 Bean后处理器在初始化之前对 messageSource 进行增强处理...
 2 Bean后处理器在初始化之后对 messageSource 进行增强处理...
 3 Bean后处理器在初始化之前对 stoneAxe 进行增强处理...
 4 Bean后处理器在初始化之后对 stoneAxe 进行增强处理...
 5 Bean后处理器在初始化之前对 steelAxe 进行增强处理...
 6 Bean后处理器在初始化之后对 steelAxe 进行增强处理...
 7 Bean后处理器在初始化之前对 spi.EmailNotifier#0 进行增强处理...
 8 Bean后处理器在初始化之后对 spi.EmailNotifier#0 进行增强处理...
 9 Bean后处理器在初始化之前对 getContextViaBean 进行增强处理...
10 Bean后处理器在初始化之后对 getContextViaBean 进行增强处理...
11 Bean后处理器在初始化之前对 getField 进行增强处理...
12 Bean后处理器在初始化之后对 getField 进行增强处理...
13 Spring正在执行默认构造函数构造Chinese实例...
14 依赖注入的值:Spring正在执行setBeanName()方法注入依赖关系...
15 Bean后处理器在初始化之前对 chinese 进行增强处理...
16 正在执行初始化方法afterPropertiesSet...
17 正在执行初始化方法init...
18 Bean后处理器在初始化之后对 chinese 进行增强处理...
19 Bean后处理器将Chinese.beanName修改为‘Java编程‘.
20 Java编程:Spring正在执行setBeanName()方法注入依赖关系...
21 我打算去砍点柴火
22 修改beanName=Java编程,钢斧砍柴好快

 

 从执行结果可以看到,受BeanPostProcessor影响,所有Bean都被插入了两条特定行为,chinese Bean由于额外实现了InitializingBean接口而多了两条额外行为。

另外可以看到虽然在配置文件中chinese的beanName被注入的是“依赖注入的值”,但是初始化之后它又被修改成了“Java编程”,所以setBeanName也被调用了两次。

从上面的例子可以看出,BeanPostProcessor接口的作用就是对容器bean进行批量处理,实际中Spring的这种后处理很有用,通常用来实现代理器,

例如BeanNameAutoProxyCreator是根据Bean实例的name属性,创建Bean实例的代理。

DefaultAdvisorProxyCreator是根据提供的Advisor对容器所有Bean实例创建代理。

 

深入了解Spring

原文:http://www.cnblogs.com/fysola/p/6366238.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!