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 后置处理器的作用
进行初始化方法之后的操作