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.输出结果:输出的结果满足需求。