• Java Spring后处理器


    Java Spring后处理器

    在Spring框架中,交给Spring管理的类信息都会被Spring底层自动加载被封装成对应的BeanDefinition对象存储beanDefinitionMap的Map集合中去,那么除了直接将类信息配置的方式外,还有别的方式可以对想要交给Spring管理的类进行针对性处理封装,这里就可以使用到Spring的后处理器。

    后处理器:是Spring对外开放的重要扩展点,允许我们介入到Bean的整个实例化流程中来,以达到动态注册BeanDefinition,动态修改BeanDefinition,以及动态修改Bean的作用


    Spring的后处理器分为两类:BeanFactoryPostProcessorBeanPostProcessor

    • BeanFactoryPostProcessor:Bean工厂后处理器,在BeanDefinitionMap填充完毕,Bean实例化之前执行
    • BeanPostProcessor:Bean后处理器,一般在Bean实例化之后,填充到单例池singletonObjects之前执行

    Bean实例化链接:Bean的实例化

    在这里插入图片描述


    BeanFactoryPostProcessor样例:

    public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
            System.out.println("beanDefinitionMap填充完毕后,Spring容器回调此方法");
    
            //功能一:修改BeanDefinition的信息
            //根据BeanName获取封装的BeanDefinition对象
            BeanDefinition myClass= configurableListableBeanFactory.getBeanDefinition("myClass");
            myClass.setBeanClassName("com.test.MyClassChange");
    
            //功能二:注册BeanDefinition到beandDefinitionMap中
            //设置BeanDefinition的Bean信息
            RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
            rootBeanDefinition.setBeanClassName("com.test.MyClassNew");
            //进行BeanDefinition注册
            DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableListableBeanFactory;
            defaultListableBeanFactory.registerBeanDefinition("myClassNew",rootBeanDefinition);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    FactoryBeanProcessor工厂后处理,可以 修改 beanBeanDefintionMap中注册的BeanBeanDefintion内容或者 新注册 BeanBeanDefintion到beanBeanDefintionMap中去,注册功能可以理解注解的实现,工厂后处理器去遍历带上注解的类,让后将其进行注册

    BeanFactoryPostProcessor类似注解实现样例:

    public class MyComponentBeanFactoryPostPocessor implements BeanDefinitionRegistryPostProcessor {
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
            // 通过扫描工具去扫描指定包及其子包下的所有类,收集使用@MyComponent的注解的类
            Map<String, Class> myComponentAnnotationMap = BaseClassScanUtils.scanMyComponentAnnotation("com.test");
            // 遍历Map,组装BeanDefinition对象
            Iterator<String> iterator = myComponentAnnotationMap.keySet().iterator();
            while (iterator.hasNext()) {
                String key = iterator.next();
                String className = myComponentAnnotationMap.get(key).getName();
                RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
                //获取待注册的类名
                rootBeanDefinition.setBeanClassName(className);
                //进行BeanDefinition注册
                beanDefinitionRegistry.registerBeanDefinition(key, rootBeanDefinition);
                System.out.println("工厂后处理器注册了" + key + "对象");
            }
        }
    
        public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注册的时候可以用专用子接口BeanDefinitionRegistryPostProcessor去注册,此接口在BeanFactoryPostProcessor之前执行


    BeanPostProcessor样例:

    public class MyBeanPostProcessor implements BeanPostProcessor {
    
    	//在init方法执行之前执行
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName + ":postProcessBeforeInitialization");
                //判断Bean的实例类型
    	        if(bean instanceof MyClass){
                MyClass myClass= (MyClass) bean;
                //MyClass中有个String属性attribute,在此处可以注入值
                myClass.setAttribute("setAttribute");
            }
            return null;
        }
        
    	//在init方法执行之后执行
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println(beanName + ":postProcessAfterInitialization");
            return null;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    BeanPostProcessor可以修改Bean的内容,先创建Bean的构造方法,再执行postProcessBeforeInitialization方法、执行Bean的其他方法(init初始化方法等)、最后执行postProcessAfterInitialization方法

    Spring的AOP代理增强就是基于此后处理的原理进行实现,可以在Bean实例中进行切面的织入

    AOP博客链接:AOP博客链接

    代理博客链接:代理博客链接

    BeanFactoryPostProcessor类似AOP实现样例:

    public class myAopBeanPostProcessor implements BeanPostProcessor {
    
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            return null;
        }
    
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    
            // 使用动态代理,对目标Bean进行增强,返回proxy对象,进而存储到单例池singletonObjects中
            Object beanProxy = Proxy.newProxyInstance(
                    bean.getClass().getClassLoader(),
                    bean.getClass().getInterfaces(),
                    (proxy, method, args) -> {
                        //1、前置增强
                        System.out.println("方法:" + method.getName() + "-开始时间:" + new Date());
                        //2、执行目标方法
                        Object result = method.invoke(bean, args);
                        //3、后置增强
                        System.out.println("方法:" + method.getName() + "-结束时间:" + new Date());
    
                        return result;
                    }
            );
    
            return beanProxy;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
  • 相关阅读:
    Reference for Ruijie Switch Configuration
    SimpleFOCStudio安装说明,免安装版本和正常安装版本
    PPT设置为本框的默认格式以及固定文本框
    基于51单片机的智能路灯控制系统(lunwen+设计说明+仿真+程序)
    word页脚的页码全都一样
    【线性代数】P2 余子式与代数余子式&异乘变零定理
    leetcode 985. Sum of Even Numbers After Queries(query之后的偶数和)
    大语言模型(LLM)综述(三):大语言模型预训练的进展
    大数据学习路线总结
    ValueAnimator的一些骚玩法
  • 原文地址:https://blog.csdn.net/qq_39004632/article/details/128017228