Spring的后置处理器实际应用

1.InstantiationAwareBeanPostProcessor后置处理器的应用场景:

 1 /**
 2  * InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,
 3  * 包括实例化对象的前后过程以及实例的属性设置
 4  */
 5 @Component
 6 public class MyInstantiation implements InstantiationAwareBeanPostProcessor {
 7     //如果你自己定义一个代理对象,并返回,那么就会使用你定义的代理对象,
 8     //如果返回null,spring就会走正常实例化流程给你创建对象
 9     @Override
10     public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
11         return null;
12     }
13 
14     //如果返回true,那么会判断是否对属性进行填充
15     @Override
16     public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
17         System.out.println("AfterInstantiation:-------"+beanName);
18         return false;
19     }
20 
21     //对属性进行具体填充
22     @Override
23     public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
24         return null;
25     }
26 }

  

 1 @Service("service")
 2 public class IndexServiceImpl implements IndexService {
 3     @Autowired
 4     private IndexDao dao;
 5     @Autowired
 6     private IndexUCC indexUcc;
 7     //构造方法
 8     public IndexServiceImpl(){
 9         System.out.println("service constructor");
10     }
11     //初始化方法
12     @PostConstruct//使用初始化方法的注解
13     public void init(){
14         System.out.println("service init");
15     }
16     @Override
17     public void query() {
18         System.out.println("dao:***"+dao.getClass().getSimpleName());
19         dao.query();
20         System.out.println("service");
21 
22 //        indexUcc.query();
23     }
24 
25     public void setDao(IndexDao dao) {
26         this.dao = dao;
27     }
28 
29     public void setIndexUcc(IndexUCC indexUcc) {
30         this.indexUcc = indexUcc;
31     }
32 }

 

  1.当postProcessAfterInstantiation()方法返回false时,就不会对属性进行创建,所以这时候IndexServiceImpl 类中的IndexDao dao属性是没有实例化的,所以在query()方法中使用dao.getClass().getSimpleName()方法会报异常

 

   2.当postProcessAfterInstantiation()方法返回true时,spring容器会对属性进行实例化,所以就会正常执行。

 

 

 

 通过上面的实例,我们在实际开发中,可以通过beanName的判读来对实例化进行控制。

   3.postProcessBeforeInstantiation方法的作用是:

    如果你自己定义一个代理对象,并返回,那么就会使用你定义的代理对象,并把它放到单例池中,如果返回null,spring就会走正常实例化流程给你创建对象。

 

运行结果就是,其他的类都是使用spring容器的实例化进程,而service是通过自己定义的代理对象实例化进程。

 总结:InstantiationAwareBeanPostProcessor 这个后置处理器的作用就是:在bean实例化的时候,判断这个bean是否需要增强(例如:是否需要aop进行处理),如果不需要增强,那么就会放到一个map集合中去,在后续增强的处理中自动忽略这个map中的bean。

2.SmartInstantiationAwareBeanPostProcessor--determineCandidateConstructors处理器的应用场景;

  当一个bean中有两个构造方法的时候,一个无参构造方法,一个有参构造方法,那么spring在进行bean初始化的时候回默认调用无参的构造方法:

  例如:如下IndexServiceImpl中有两个构造方法

 

 那么在spring进行实例化的过程中:

 

 而如果我们想要执行有参的构造方法,则需要在有参构造方法上面加上@Autowired注解即可:

 

 执行结果:发现spring执行了有参的构造方法

 Spring推断构造方法的过程:在这个过程中,如果推断出有一个构造方法加了@Autowired注解,那么spring会把它放到一个临时变量当中,在判断临时变量是否为空,如果不为空,则把这个变量转换成临时数组返回出去,而如果构造方法都没有加@Autowired注解,那么spring就无法判断要把哪个加入到临时变量中,所以最后返回一个null,然后spring根据返回的null来使用默认的构造方法。

3.MergedBeanDefinitionPostProcessor---postProcessMergedBeanDefinition 后置处理器的作用

  用来缓存注解信息。

4.SmartInstantiationAwareBeanPostProcessor---getEarlyBeanReference 后置处理器的作用

  得到一个提前暴露的对象----对象不是bean(在spring容器当中,并且由sping自己产生的)

5.InstantiationAwareBeanPostProcessor--postProcessAfterInstantiation 后置处理器的作用

  判断你的bean需不需要完成属性填充。

6.InstantiationAwareBeanPostProcessor---postProcessPropertyValues 后置处理器的作用

  进行属性填充---自动注入

7.BeanPostProcessor----postProcessBeforeInitialization 后置处理器的作用

  进行初始化方法之前的操作

8.BeanPostProcessor----postProcessAfterInitialization 后置处理器的作用

  进行初始化方法之后的操作

9.destory方法,进行bean的销毁动作

 

posted @ 2020-06-08 07:36  WK_BlogYard  阅读(1088)  评论(0编辑  收藏  举报