Spring的后处理器

Spring后处理器

  • Spring后处理器是Spring对外开放的重要拓展点(让我们可以用添加自己的逻辑),允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition(向BeanDefitionMap中添加BeanDefition对象的过程),动态修改BeanDefition,以及动态修改Bean的作用。Spring主要有两种后处理器
    • BeanFactoryPostprocessor:Bean工厂后处理器,(执行时机)在BeanDefinitionMap填充完毕,Bean实例化之前执行
    • BeanPostProcessor:Bean后处理器,(执行时机)一般在Bean实例化后,填充到单例池singletonObjects之前执行

Bean工厂后处理器-BeanFactoryPostProcessor

  • BeanFactoryPostProcessor是一个接口规范,实现该接口的类只要交由Spring容器管理(即在配置文件中注册该类称为Bean对象)的话,那么Spring就会回调该接口的方法,用于对BeanDefition注册和修改功能
  • BeanFactoryPostProcessor定义如下
    • //
      // Source code recreated from a .class file by IntelliJ IDEA
      // (powered by FernFlower decompiler)
      //
      
      package org.springframework.beans.factory.config;
      
      import org.springframework.beans.BeansException;
      
      @FunctionalInterface
      public interface BeanFactoryPostProcessor {
          void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
      }
      
修改beanDefinition对象
  • 创建一个实现类(修改beanDefinition对象

    • package com.example.PostProcessor;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanDefinition;
      import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      
      public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              System.out.println("beanDefinitionMap填充完毕后会回调该方法");
              // todo 修改Map集合中的BeanDefinition对象
              BeanDefinition userService = beanFactory.getBeanDefinition("userService");
              userService.setBeanClassName("com.example.DAO.Impl.UserDAOImpl");
      
          }
      }
      
  • 测试类

    • package com.example.Test;
      
      
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      public class TestApplicationContext {
          public static void main(String[] args)  {
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
              System.out.println(context.getBean("userService"));
          }
      }
      
  • 运行结果如下

    • Spring的后处理器_第1张图片

    • 显然bean对应的类被改变了 
添加beanDefiniton对象
方法一
  • 创建一个类(添加beanDefiniton对象
    • package com.example.PostProcessor;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanDefinition;
      import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.support.DefaultListableBeanFactory;
      import org.springframework.beans.factory.support.RootBeanDefinition;
      
      public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
              // todo 向Map集合中添加一个BeanDefinition对象,即在配置文件中没有注册
              // 创建一个新的beanDefinition对象
              BeanDefinition beanDefinition = new RootBeanDefinition();
              // 设置bean对应的类
              beanDefinition.setBeanClassName("com.example.DAO.Impl.UserDAOImpl");
              DefaultListableBeanFactory listableBeanFactory = (DefaultListableBeanFactory) beanFactory;
              // 添加该beanDefinition对象
              listableBeanFactory.registerBeanDefinition("UserDAO", beanDefinition);
          }
      }
      

      在配置文件中没有配置UserDAO了

  • 测试类

    • package com.example.Test;
      
      
      import com.example.DAO.Impl.UserDAOImpl;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class TestApplicationContext {
          public static void main(String[] args) {
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
              
              System.out.println(context.getBean(UserDAOImpl.class));
          }
      }
      
  • 运行结果

    • Spring的后处理器_第2张图片

                beanDefinition对象成功添加


方法二
  • Spring提供了一个BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor专门用于注册BeanDefinition操作
    • //
      // Source code recreated from a .class file by IntelliJ IDEA
      // (powered by FernFlower decompiler)
      //
      
      package org.springframework.beans.factory.support;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
      
      public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
          void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
      }
      
  • 创建一个类实现后处理器BeanFactoryPostProcessor的子接口BeanDefinitionRegistryPostProcessor(记得将该类注册到Spring容器中)

    • package com.example.PostProcessor;
      
      import org.springframework.beans.BeansException;
      import org.springframework.beans.factory.config.BeanDefinition;
      import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
      import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
      import org.springframework.beans.factory.support.BeanDefinitionRegistry;
      import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
      import org.springframework.beans.factory.support.DefaultListableBeanFactory;
      import org.springframework.beans.factory.support.RootBeanDefinition;
      
      public class MyBeanFactoryPostProcessor02 implements BeanDefinitionRegistryPostProcessor {
          @Override
          public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
              // 注册beanDefinition
              BeanDefinition beanDefinition = new RootBeanDefinition();
              beanDefinition.setBeanClassName("com.example.DAO.Impl.UserDAOImpl");
              registry.registerBeanDefinition("UserDAO", beanDefinition);
          }
          @Override
          public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
      
          }
      }
      

      实现添加beanDefiniton就会简单很多

  • 测试类

    • package com.example.Test;
      
      
      import com.example.DAO.Impl.UserDAOImpl;
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class TestApplicationContext {
          public static void main(String[] args) {
              ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
              System.out.println(context.getBean(UserDAOImpl.class));
          }
      }
      
  • 运行结果如下

    • Spring的后处理器_第3张图片

完整流程图 

Spring的后处理器_第4张图片

        
 


自定义@Component
  • 案例
    • 使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描
  • 要求
    • 自定义@MyComponent注解,使用在类上
    • 使用资料中提供好的包扫描工具BaseClassScanUtils完成指定包的类扫描
    • 自定义BeanFactoryPostProcessor完成注解@MyComponent的解析,解析最终被Spring管理

资料没有找到,明天再来

你可能感兴趣的:(Spring,5,spring,java,后端)