(一)功能

实现了BeanDefinitionRegistryPostProcessor接口的类,可以在覆写的postProcessBeanDefinitionRegistry方法中向spring容器注册bean

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

(二)实现

(1)定义一个pojo

@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestBeanA {

    private String name;

    private Integer age;

    public void say() {
        System.out.println("TestBeanA");
        System.out.println(this);
    }
}

(2)实现我们自己的BeanDefinitionRegistryPostProcessor

@Configuration
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {

        BeanDefinitionBuilder b = BeanDefinitionBuilder.genericBeanDefinition(TestBeanA.class)
                .addPropertyValue("name", "vincent")
                .addPropertyValue("age", 12);
        registry.registerBeanDefinition("testBeanA", b.getBeanDefinition());
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

    }
}

 (3)测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class AppTest {

    @Autowired
    TestBeanA testBeanA;

    @Test
    public void beanATest(){
        testBeanA.say();
    }
}

(4)输出结果

TestBeanA
TestBeanA(name=vincent, age=12)

(三)实际应用

  我们可以利用BeanDefinitionRegistryPostProcessor来配置springboot的多数据源。

  (四) 原理

AbstractApplicationContext的refresh方法中registerBeanPostProcessors(beanFactory)下面代码中加粗斜体字。

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				initMessageSource();

				// Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				onRefresh();

				// Check for listener beans and register them.
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

  

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄