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")); } }
-
-
运行结果如下
- 显然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)); } }
-
-
运行结果
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)); } }
-
-
运行结果如下
完整流程图
自定义@Component
- 案例
- 使用Spring的BeanFactoryPostProcessor扩展点完成自定义注解扫描
- 要求
- 自定义@MyComponent注解,使用在类上
- 使用资料中提供好的包扫描工具BaseClassScanUtils完成指定包的类扫描
- 自定义BeanFactoryPostProcessor完成注解@MyComponent的解析,解析最终被Spring管理
资料没有找到,明天再来