Bean 的生命周期 之 后处理Bean

  这里先把Bean 的生命周期总结一下,然后引出后处理Bean

 

  首先,Bean 的生命周期总共有11步:

 

1.instantiate bean对象实例化

2.populate properties 封装属性

3.如果Bean实现BeanNameAware 执行 setBeanName

4.如果Bean实现BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext

5.如果存在类实现 BeanPostProcessor(后处理Bean,执行postProcessBeforeInitialization

6.如果Bean实现InitializingBean 执行 afterPropertiesSet

7.调用<bean init-method="init"> 指定初始化方法 init

8.如果存在类实现 BeanPostProcessor(处理Bean,执行postProcessAfterInitialization

9.执行业务处理

10.如果Bean实现 DisposableBean 执行 destroy

11.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy

 


通过测试的话,我们能很容易的验证这11个步骤,但是这11个步骤里面最重要的还是第5步和第8步

然而,第五步是在Bean初始化之前执行,我不知道这一步有什么用(请大神指点)

 

但是我知道,在第8步里面,可以添加一些自己的代码,就可以实现对方法的增强!也就是我们执行业务(第九步)之前就可以调用。然后对指定的方法进行增强

大家一定要注意,第五步和第八步室友前提的存在类实现 BeanPostProcessor 这里用户色标出希望大家注意!!!!!!!

也就是我们自己要定义一个后处理器,并实现其中的两个方法!如下代码:

 1 public class MyBeanPostProcessor implements BeanPostProcessor{
 2     /**
 3      * bean:实例对象
 4      * beanName:在配置文件中配置的类的标识.
 5      */
 6     public Object postProcessBeforeInitialization(Object bean, String beanName)
 7             throws BeansException {
 8         System.out.println("第五步:初始化之前执行...");
 9         return bean;
10     }
11 
12     public Object postProcessAfterInitialization(final Object bean, String beanName)
13             throws BeansException {
14         System.out.println("第八步:初始化后执行...");
15     }
16 }

 

这就是一个后处理器!没初始化一个Bean,都会调用第五步和第八步,所以,通过这一点,我们就可以增强自己的代码!

 

在第八步里面(postProcessAfterInitialization()),我们就可以编写自己的增强。

但是,这里注意一点就是:我们定义的这个后处理器,也是需要在配置文件中添加的。Spring在初始化bean过程中如果发现bean实现了BeanPostProcessor 接口,将会将其注册为bean后处理器,它对spring容器下的所有bean起作用,任何bean在 初始化过程都会通过bean后处理器做额外增强操作。

如下是测试类的代码:

public void demo1() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
                "applicationContext.xml");
        
        CustomerService customerService = (CustomerService) applicationContext.getBean("customerService");
        customerService.add();
        customerService.find();
        
        applicationContext.close();
    }

 

但是我们不想让所有的Bean 都被增强,这时候就可以使用动态代理来解决这个问题,可以做到只对某个方法进行增强。

代码如下:

 1 public Object postProcessAfterInitialization(final Object bean, String beanName)
 2             throws BeansException {
 3         System.out.println("第八步:初始化后执行...");
 4         // 动态代理:
 5         if(beanName.equals("customerService")){
 6             Object proxy = Proxy.newProxyInstance(bean.getClass().getClassLoader(), bean.getClass().getInterfaces() , new InvocationHandler() {
 7                 // 调用目标方法的时候,调用invoke方法.
 8                 public Object invoke(Object proxy, Method method, Object[] args)
 9                         throws Throwable {
10                     if("add".equals(method.getName())){
11                         System.out.println("权限校验...");
12                         Object result = method.invoke(bean, args);
13                         System.out.println("权限校验后。。。");
14                         //System.out.println(System.currentTimeMillis());
15                         return result;
16                     }
17                     return method.invoke(bean, args);
18                 }
19             });
20             return proxy;
21         }
22         return bean;
23     }

 

这里用到了动态代理,只对customerService的add方法进行增强!!!

这里还要注意一点,我们这用的是JDK的动态代理,所以被代理的类必须实现某个接口才行!!!,所以,customerService是实现类接口的类!

 

而测试结果就很明显了:

在调用add方法之后,会自动调用代理方法中的两个输出语句!

 其实后面学习的动态代理用到的就是后处理Bean的知识.

posted @ 2017-08-03 14:17  money云  阅读(421)  评论(0编辑  收藏  举报