Spring Bean 后置处理器BeanPostProcessor

浅浅的花香味﹌ 2022-04-25 05:02 371阅读 0赞

文章目录

    • Spring Bean 后置处理器BeanPostProcessor
    • BeanPostProcessor实现类代码演示
    • BeanPostProcessor生成代理对象

Spring Bean 后置处理器BeanPostProcessor

Spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after()

可以配置多个 BeanPostProcessor 接口,通过设置 BeanPostProcessor 实现的 Ordered 接口提供的 order 属性来控制这些 BeanPostProcessor 接口的执行顺序。

ApplicationContext 会自动检测由 BeanPostProcessor 接口的实现定义的 bean,注册这些 bean 为后置处理器,然后通过在容器中创建 bean,在适当的时候调用它。

在这里插入图片描述

  • Factory hook(勾子) that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.
  • spring提供工厂勾子,用于修改实例对象,可以生成代理对象,是AOP底层。

    模拟
    A a =new A();
    a = B.before(a) —> 将a的实例对象传递给后处理bean,可以生成代理对象并返回。
    a.init();
    a = B.after(a);
    a.addUser(); //生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)
    a.destroy()

BeanPostProcessor实现类代码演示

  • BeanPostProcessor实现类1,同时实现getOrder方法来控制这些 执行顺序

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;

    public class PostProcessor implements BeanPostProcessor,Ordered {

    1. //可以在初始化 bean 的之前和之后实现更复杂的逻辑。
    2. //在Init-method的前后执行
    3. @Override
    4. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    5. System.out.println("postProcessBeforeInitialization1:" + beanName);
    6. ((InitHelloWorld)bean).getMessage();
    7. return bean;
    8. }
    9. @Override
    10. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    11. System.out.println("postProcessAfterInitialization1:" + beanName);
    12. ((InitHelloWorld)bean).getMessage();
    13. return bean;
    14. }
    15. @Override
    16. public int getOrder() {
    17. return 0;
    18. }

    }

  • BeanPostProcessor实现类2

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.core.Ordered;

    public class PostProcessor2 implements BeanPostProcessor,Ordered {

    1. //可以在初始化 bean 的之前和之后实现更复杂的逻辑。
    2. //在Init-method的前后执行
    3. @Override
    4. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    5. System.out.println("postProcessBeforeInitialization2:" + beanName);
    6. ((InitHelloWorld)bean).getMessage();
    7. return bean;
    8. }
    9. @Override
    10. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    11. System.out.println("postProcessAfterInitialization2:" + beanName);
    12. ((InitHelloWorld)bean).getMessage();
    13. return bean;
    14. }
    15. @Override
    16. public int getOrder() {
    17. return 1;
    18. }

    }

  • 配置

    <?xml version=”1.0” encoding=”UTF-8”?>

  1. <bean id="initHelloWorld" class="com.cc.study.lifecycle.InitHelloWorld"
  2. init-method="init" destroy-method="destroy">
  3. <property name="message" value="Hello World!"></property>
  4. </bean>
  5. <bean id="postProcessor" class="com.cc.study.lifecycle.PostProcessor"></bean>
  6. <bean id="postProcessor2" class="com.cc.study.lifecycle.PostProcessor2"></bean>
  7. </beans>
  • InitHelloWorld

    public class InitHelloWorld{

    1. private String message;
    2. public void setMessage(String message){
    3. this.message = message;
    4. }
    5. public void getMessage(){
    6. System.out.println("Your Message : " + message);
    7. }
    8. public void init(){
    9. System.out.println("Bean is going through init.");
    10. }
    11. public void destroy(){
    12. System.out.println("Bean will destroy now.");
    13. }

    }

  • 测试

    @Test

    1. public void demo(){
    2. String xmlPath = "lifecycle2.xml";
    3. AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
    4. InitHelloWorld initHelloWorld = applicationContext.getBean("initHelloWorld",InitHelloWorld.class);
    5. initHelloWorld.getMessage();
    6. applicationContext.registerShutdownHook();
    7. }

在这里插入图片描述

BeanPostProcessor生成代理对象

  • MyBeanPostProcessor

    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;

    public class MyBeanPostProcessor implements BeanPostProcessor {

    1. @Override
    2. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    3. System.out.println("前方法 : " + beanName);
    4. return bean;
    5. }
    6. @Override
    7. public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException {
    8. System.out.println("后方法 : " + beanName);
    9. // bean 目标对象
    10. // 生成 jdk 代理
    11. return Proxy.newProxyInstance(
    12. MyBeanPostProcessor.class.getClassLoader(),
    13. bean.getClass().getInterfaces(),
    14. new InvocationHandler(){
    15. @Override
    16. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    17. System.out.println("------开启事务");
    18. System.out.println("调用方法:" + method.getName());
    19. //执行目标方法
    20. Object obj = method.invoke(bean, args);
    21. System.out.println("------提交事务");
    22. return obj;
    23. }});
    24. }

    }

  • 配置

    <?xml version=”1.0” encoding=”UTF-8”?>








  • BookDaoImpl

    public class BookDaoImpl implements BookDao {

    1. @Override
    2. public void addBook() {
    3. System.out.println("di add book");
    4. }

    }

  • 测试

    @Test

    1. public void demo(){
    2. String xmlPath = "lifecycle3.xml";
    3. AbstractApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
    4. BookDao bookDao = applicationContext.getBean("bookDaoId",BookDao.class);
    5. bookDao.addBook();
    6. }

在这里插入图片描述

注意:
问题1:后处理bean作用某一个目标类,还是所有目标类?
所有
问题2:如何只作用一个?
通过“参数2”beanName进行控制

发表评论

表情:
评论列表 (有 0 条评论,371人围观)

还没有评论,来说两句吧...

相关阅读