• 1.spring源码-BeanPostProcessor后置处理器


    1.BeanPostProcessor接口的介绍:

    BeanPostProcessor是一个接口,其中有两个方法,postProcessBeforeInitialization和postProcessAfterInitialization两个方法,这两个方法分别是在spring容器中的bean初始化前后执行,所以spring容器中的每一个bean对象初始化前后,都会执行BeanPostProcessor接口的实现类的这两个方法。因此我们可以在每个bean对象初始化前后,加上自己的逻辑。实现方式:自定义一个BeanPostProcessor接口的实现类A,然后在类A的postProcessBeforeInitialization和postProcessAfterInitialization方法里面写上自己的逻辑。

    看一下BeanPostProcessor接口的代码:

     1 public interface BeanPostProcessor {
     2     @Nullable
     3     default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     4         return bean;
     5     }
     6 
     7     @Nullable
     8     default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
     9         return bean;
    10     }
    11 }
    postProcessBeforeInitialization和postProcessAfterInitialization方法中的bean参数,就是将要初始化或已经初始化的spring容器中的bean对象。

    2.如何证明spring容器中的bean对象初始化前后,都会执行BeanPostProcessor实现类的postProcessBeforeInitialization和postProcessAfterInitialization两个方法:
      a.首先spring中有一个类AbstractAutowireCapableBeanFactory
      b.展示AbstractAutowireCapableBeanFactory的三个个方法:spring容器初始化前后,都会执行它的applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorsAfterInitialization
       两个方法,而在这两个方法中都会遍历BeanPostProcessor的所有实现类,并分别执行BeanPostProcessor实现类的前置和后置方法。
     1     public List<BeanPostProcessor> getBeanPostProcessors() {
     2         return this.beanPostProcessors;
     3     }
     4     
     5     public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
     6         Object result = existingBean;
     7 
     8         Object current;
     9         //遍历所有的BeanPostProcessor实现类,spring容器中每个bean对象都要执行所有的BeanPostProcessor实现类的前置方法(postProcessBeforeInitialization)
    10         for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
    11             BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
    12             current = beanProcessor.postProcessBeforeInitialization(result, beanName);
    13             if(current == null) {
    14                 return result;
    15             }
    16         }
    17 
    18         return result;
    19     }
    20 
    21     public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException {
    22         Object result = existingBean;
    23 
    24         Object current;
    25         //遍历所有的BeanPostProcessor实现类,spring容器中每个bean对象都要执行所有的BeanPostProcessor实现类的后置方法(postProcessAfterInitialization)
    26         for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
    27             BeanPostProcessor beanProcessor = (BeanPostProcessor)var4.next();
    28             current = beanProcessor.postProcessAfterInitialization(result, beanName);
    29             if(current == null) {
    30                 return result;
    31             }
    32         }
    33 
    34         return result;
    35     }
    写一个需求:
    现在我有两个类分别是Dog和Bird,这两个类都有一个属性int类型age属性,现在我想把这两个类交给spring容器来管理,并在初始化时,让Dog的对象的age属性值为15,
    让Bird的对象的age属性值为9. 
    实现步骤:
      1.先写好Dog和Bird两个类:
     1 @Component
     2 public class Bird {
     3    
     4     private int age;
     5 
     6     @Override
     7     public String toString() {
     8         return "Bird [age=" + age + "]";
     9     }
    10 }
     1 @Component
     2 public class Dog {
     3 
     4      private int age;//狗一般活到15岁
     5 
     6     @Override
     7     public String toString() {
     8         return "Dog [age=" + age + "]";
     9     }
    10 }

      2.然后在写一个类MyBeanPostProcessor实现bean后置处理器接口BeanPostProcessor:

     1 @Component
     2 public class MyBeanPostProcessor implements BeanPostProcessor {
     3     //在bean对象初始化之前被调用 bean是Spring容器管理一个对象,beanName就是当前对象在Spring容器中关联的key
     4     @Override
     5     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
     6         if(bean.getClass()==Dog.class){
     7           try{
     8               Field field =    bean.getClass().getDeclaredField("age");
     9               field.setAccessible(true);
    10               field.set(bean, 15);
    11           }catch(Exception ex){
    12               ex.printStackTrace();
    13           }
    14         }else if(bean.getClass()==Bird.class){
    15              try{
    16                   Field field =    bean.getClass().getDeclaredField("age");
    17                   field.setAccessible(true);
    18                   field.set(bean, 9);
    19               }catch(Exception ex){
    20                   ex.printStackTrace();
    21               }
    22         }
    23         return bean;
    24     }
    25 
    26     //在bean对象初始化之后被调用 bean是Spring容器管理一个对象,beanName就是当前对象在Spring容器中关联的key
    27     @Override
    28     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    29         // TODO Auto-generated method stub
    30         return bean;
    31     }
    32 }

      3.写个测试类来查看一下结果:

     1 public class TestMain {
     2 
     3     public static void main(String[] args) {
     4         // 1.获得Spring容器对象
     5         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ApplicationConfig.class);
     6         Dog dog = (Dog)context.getBean("dog");
     7         System.out.println(dog);
     8         Bird bird = (Bird)context.getBean("bird");
     9         System.out.println(bird);
    10     }
    11 }

      4.输出结果:输出的结果满足需求。






















  • 相关阅读:
    day29 作业
    day 29 线程
    day28 进程
    day27 服务端 和客户端
    day26 作业
    day26 网络编程
    java基础 反射
    python 计时
    mongodb 批量插入唯一索引冲突
    js hook
  • 原文地址:https://www.cnblogs.com/WNof11020520/p/10598745.html
Copyright © 2020-2023  润新知