发
2.1.1 BeanDefinitionRegistryPostProcessor 它是Spring框架的一个扩展点,用于对Bean定义的注册过程进行干预和定制。
2.1.2 BeanDefinitionRegistryPostProcessor 它继承BeanFactoryPostProcessor接口,并在其基础上扩展了一个新的方法,即:postProcessBeanDefinitionRegistry()方法。
BeanDefinitionRegistryPostProcessor 在Spring容器初始化时,首先会读取应用程序中的配置文件,并解析出所有的Bean定义,然后将这些Bean定义注册到容器中。
在这个过程中,BeanDefinitionRegistryProcessor提供了一种机制,允许开发人员在Bean定义注册之前和之后对Bean定义进行自定义处理,例如添加,修改或删除Bean定义等。
具体来说,BeanDefinitionRegistryPostProcessor提供了以下两个方法:
2.3.1 postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry):
该方法在所有Bean定义加载完成之后,Bean实例化之前被调用,允许开发人员对Bean定义进行自定义修改,例如添加,修改或删除Bean定义等。
2.3.2 postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory):
该方法是继承自BeanFactoryPostProcessor接口的方法,用于在BeanFactory完成实例化之后对BeanFactory进行后置处理。
那么我们通过BeanDefinitionRegistryPostProcessor接口,开发人员可以在Spring容器启动时干预Bean的注册过程,从而实现对Bean的自定义处理。
3.1.1 Entity 类 (MyBean)
- public class MyBean {
- private String message = "Hello, World!";
-
- public String getMessage() {
- return message;
- }
-
- public void setMessage(String message) {
- this.message = message;
- }
- }
3.1.2 手写一个接口
这个接口实现BeanDefinitionRegistryPostProcessor和接口PriorityOrdered,在postProcessBeanDefinitionRegistry方法中对bean的操作进行增删查改
- @Component
- public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
- /**
- * 重写BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
- */
- @Override
- public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
-
- // 创建一个RootBeanDefinition实例,该实例对应的BeanClass是MyBean
- RootBeanDefinition beanDefinition = new RootBeanDefinition(MyBean.class);
- // 向BeanDefinitionRegistry注册MyBean的BeanDefinition
- registry.registerBeanDefinition("myBean", beanDefinition);
-
- // 查询和修改
- BeanDefinition myBean = registry.getBeanDefinition("myBean");
- System.out.println(myBean);
- // 删除
- registry.removeBeanDefinition("myBean");
-
- }
-
- /**
- * 重写BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法
- */
- @Override
- public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
-
- }
-
- @Override
- public int getOrder() {
- return 1;
- }
- }
3.1.3 启动类
- @SpringBootApplication
- public class FactorybeanDemoApplication {
-
- public static ConfigurableApplicationContext context ;
-
- public static void main(String[] args) {
- context = SpringApplication.run(FactorybeanDemoApplication.class, args);
- MyBean bean = context.getBean(MyBean.class);
- System.out.println("================"+bean.getMessage()+"===================");
- }
- }
- Exception in thread "restartedMain" java.lang.reflect.InvocationTargetException
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
- at java.lang.reflect.Method.invoke(Method.java:498)
- at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
- Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.factorybean.factorybeandemo.factorybean.test.MyBean' available
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:343)
- at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:335)
- at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1101)
- at com.factorybean.factorybeandemo.FactorybeanDemoApplication.main(FactorybeanDemoApplication.java:17)
- ... 5 more
- 2023-10-22 14:43:22.448 INFO 73304 --- [ restartedMain] c.f.f.FactorybeanDemoApplication : Started FactorybeanDemoApplication in 1.333 seconds (JVM running for 1.87)
- ================Hello, World!===================
3.2.1 配置类 (MyPostBeanRegistar)
- @Configuration
- public class MyPostBeanRegistar implements BeanDefinitionRegistryPostProcessor {
- @Override
- public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
-
- System.out.println("postProcessBeanDefinitionRegistry is invoked");
-
- String clzz= Base.class.getName();
-
-
- for(int i=0;i<2;i++){
- if(!beanDefinitionRegistry.containsBeanDefinition(i+""))
- ResgistarUtils.registerBeanDefinations(i+"",clzz,beanDefinitionRegistry);
- }
-
- }
-
- @Override
- public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
- System.out.println("postProcessBeanFactory is invoked");
- }
- }
3.2.2 注册Utils类 (ResgistarUtils)
- public class ResgistarUtils {
-
- /**
- * 注册工具类方法
- * @param className
- * @param clzz
- * @param beanDefinitionRegistry
- */
- public static void registerBeanDefinations(String className, String clzz, BeanDefinitionRegistry beanDefinitionRegistry){
-
-
- /**
- * 通过 工厂方法来注入Bean
- */
- BeanDefinitionBuilder builder= BeanDefinitionBuilder.genericBeanDefinition(MyfactoryBean.class);
-
- builder.addPropertyValue("type",clzz);
- builder.addPropertyValue("name",className);
- builder.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
-
- AbstractBeanDefinition beanDefinition = builder.getBeanDefinition();
- if(className.equals("0")) {
- beanDefinition.setPrimary(true);
- }else{
- //beanDefinition.s
- }
-
- BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className);
- BeanDefinitionReaderUtils.registerBeanDefinition(holder, beanDefinitionRegistry);
- }
- }
3.2.3 工厂bean接口实现
- public class MyfactoryBean implements FactoryBean
- public Class> getType() {
- return type;
- }
-
- public void setType(Class> type) {
- this.type = type;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- private Class> type;
- private String name;
-
- @Override
- public Object getObject() throws Exception {
- System.out.println("getObject");
- if(this.name.equals("0")){
- return new TestA();
- }else if(this.name.equals("1")){
- return new TestB();
-
- }
- throw new ClassNotFoundException("not found Base by name=["+name+"]");
- }
-
- @Override
- public Class> getObjectType() {
- return type;
- }
-
- }
3.2.4 Entity 类 (Base、TestA、TestB)
- public interface Base {
- void print();
- }
- public class TestA implements Base {
-
- public TestA(){
- System.out.println("TestA 够着");
- }
- @Override
- public void print() {
- System.out.println("testA aaa");
- }
- }
- public class TestB implements Base {
-
- public TestB(){
- System.out.println("TestB 够着");
- }
-
- @Override
- public void print() {
- System.out.println("testB bbbb ");
- }
- }
3.2.5 测试 Controller 类 (TestController)
- @RestController
- public class TestController {
-
- @Autowired
- Base base1;
-
- // @Autowired
- // @Qualifier("1")
- @Resource(name = "1")
- Base base2;
-
- @GetMapping("/testprint")
- public String print(){
- base1.print();
- base2.print();
- return "testprint";
- }
- }
3.2.6 启动类
- @SpringBootApplication
- public class FactorybeanDemoApplication {
-
- public static ConfigurableApplicationContext context ;
-
- public static void main(String[] args) {
- context = SpringApplication.run(FactorybeanDemoApplication.class, args);
- TestA testA = (TestA)context.getBean("0");
- testA.print();
- TestB testB = (TestB)context.getBean("1");
- testB.print();
- }
- }
3.3 统一 pom
- "1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0modelVersion>
-
- <groupId>com.factorybeangroupId>
- <artifactId>factorybean-demoartifactId>
- <version>0.0.1-SNAPSHOTversion>
- <packaging>jarpackaging>
-
- <name>factorybean-demoname>
- <description>factorybean注入方式 project for Spring Bootdescription>
-
- <parent>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-parentartifactId>
- <version>2.1.0.RELEASEversion>
- <relativePath/>
- parent>
-
- <properties>
- <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
- <java.version>1.8java.version>
- properties>
-
- <dependencies>
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-webartifactId>
- dependency>
-
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-devtoolsartifactId>
- <scope>runtimescope>
- dependency>
- <dependency>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-starter-testartifactId>
- <scope>testscope>
- dependency>
- dependencies>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.bootgroupId>
- <artifactId>spring-boot-maven-pluginartifactId>
- plugin>
- plugins>
- build>
-
-
- project>
https://zhuanlan.zhihu.com/p/653695574
https://blog.csdn.net/u014365523/article/details/118683004
https://blog.csdn.net/f5465245/article/details/123551991