浅析Spring IoC源码(四)分析BeanPostProcessor(1)
  fztgkkRjHIsV 2023年11月14日 24 0


BeanPostProcessor是什么呢,有什么作用呢,打开源代码先看看


浅析Spring IoC源码(四)分析BeanPostProcessor(1)_java

这个接口的注释中原作者说明了该接口的作用:

“工厂钩子允许用户自定义修改创建的bean实例,应用上下文可以在ben的定义中自动检测beanPostProecessor,并且将其应用于随后创建的任意bean中,并且可以通过factory给其他的类进行注册然后使用”

说白了,就是我们可以自定义的去修改spring给我们创建的类,给了我们一个二次修改bean的机会,这种设计思路与spring的“开闭原则”相符合,没有过度分装,举例来说,我们根据beanDefinition去查找一个Teacher,找到之后spring给我们实例化这个Teacher,但是我们用这个teacher的时候,发现这个teacher会抽烟,我们可以修改这个老师会抽烟的属性,这样就得到了一个完美的老师,这个完美的老师授课结束后,我们再告诉他你可以接着抽烟了,所以spring给我们想的还是很周到的~

 

再看这个接口定义的2个方法


浅析Spring IoC源码(四)分析BeanPostProcessor(1)_spring_02

BeanPostProcessor这个接口就2个方法,根据这2个方法的名称,我们就大概知道这2个方法的做什么的了

postProcessBeforeInitialization在“初始化之前处理”

postProcessAfterInitialization在“初始化之后处理”

废话不多说,我们就实现一个上面讲述的例子,大家更加深入的理解一下BeanPostProcessor这个作用

Teacher.Java

package org.study.spring.beanpostprocessor.demo;  
  
public class Teacher {  
      
/**
     * 老师的姓名
     */  
private String name;  
      
/**
     * 年龄
     */  
private int age;  
      
/**
     * 是否抽烟
     */  
private boolean smoking;  
      
/**
     * 老师教授的课程
     */  
private String language;  
      
/**
     * 临时变量,默认抽烟
     */  
private boolean tempSmoking = true;  
      
      
public Teacher() {  
          
    }  
       
public boolean isTempSmoking() {  
return tempSmoking;  
    }  
  
  
public void setTempSmoking(boolean tempSmoking) {  
this.tempSmoking = tempSmoking;  
    }  
  
  
public String getName() {  
return name;  
    }  
  
public void setName(String name) {  
this.name = name;  
    }  
  
public int getAge() {  
return age;  
    }  
  
public void setAge(int age) {  
this.age = age;  
    }  
  
public boolean isSmoking() {  
return smoking;  
    }  
  
public void setSmoking(boolean smoking) {  
this.smoking = smoking;  
    }  
  
  
public String getLanguage() {  
return language;  
    }  
  
public void setLanguage(String language) {  
this.language = language;  
    }  
      
public void teach(){  
"I am :"+name+" and I will teach you :"+language + " and I "+(tempSmoking?"will":"will not")+" smoking");  
    }  
      
  
}


ChangeTeacherSmokingBeanPostProcessor.java


package org.study.spring.beanpostprocessor.demo;  
  
import org.springframework.beans.BeansException;  
import org.springframework.beans.factory.config.BeanPostProcessor;  
  
public class ChangeTeacherSmokingBeanPostProcessor implements BeanPostProcessor{  
      
  
/**
     * 初始化之前处理
     */  
public Object postProcessBeforeInitialization(Object bean, String beanName)  
throws BeansException {  
/**
         * 只处理该bean的类型是Teacher的
         */  
if(bean instanceof Teacher){  
            Teacher teacher = (Teacher)bean;  
/**
             * 实例化之前,要吧所有抽烟的都改成不抽烟的
             */  
if(teacher.isSmoking()){  
false);  
            }  
        }  
return bean;  
    }  
  
public Object postProcessAfterInitialization(Object bean, String beanName)  
throws BeansException {  
return bean;  
    }  
  
}


bean-post-processor-teacher.xml


<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"  
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"  
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd  
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd  
        http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd  
>  
   
<bean id="teacher" class="org.study.spring.beanpostprocessor.demo.Teacher">  
<property name="name" value="孔浩"/>  
<property name="age" value="32"/>  
<property name="smoking" value="true"/>  
<property name="language" value="java"/>  
</bean>  
          
<bean id="changeTeacher" class="org.study.spring.beanpostprocessor.demo.ChangeTeacherSmokingBeanPostProcessor"/>  
            
  
</beans>

ChangeTeacherSmokingBeanPostProcessorTest.java


package org.study.spring.beanpostprocessor.demo;  
  
import org.junit.Test;  
import org.springframework.context.ApplicationContext;  
import org.springframework.context.support.ClassPathXmlApplicationContext;  
  
public class ChangeTeacherSmokingBeanPostProcessorTest{  
      
      
@Test  
public void test2() throws Exception{  
new ClassPathXmlApplicationContext("bean-post-processor-teacher.xml");  
"teacher",Teacher.class);  
         teacher.teach();  
           
    }  
  
}



运行结果


浅析Spring IoC源码(四)分析BeanPostProcessor(1)_xml_03

上面的例子只是说明,spring在初始化之前,给了我们开发者二次修改的机会,beanPostProcessor这个类是“spring”开闭原则的典型实现,下一节详细讲述它在项目中的具体运用~


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: Redis使用场景 下一篇: AB测试结果分析
  1. 分享:
最后一次编辑于 2023年11月14日 0

暂无评论

推荐阅读
fztgkkRjHIsV