• 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的知识.

  • 相关阅读:
    axb_2019_fmt32 盲打和格式化字符串
    ciscn_2019_final_3 需要避开当前free的chunk的下一个chunk不能超过arena的边界
    xdctf2015_pwn200
    valarray类
    Mysql 常用命令.
    如何处理IO
    等号两边自动添加括号
    Request JSON
    开机小脚本自动打开sublime text 和git-bash
    git 同步勾子
  • 原文地址:https://www.cnblogs.com/ilovessf/p/7279457.html
Copyright © 2020-2023  润新知