1. 程式人生 > >springboot學習總結(十二)BeanDefinitionRegistryPostProcessor向spring容器中註冊bean

springboot學習總結(十二)BeanDefinitionRegistryPostProcessor向spring容器中註冊bean

strac autowired true all 方法 brush autowire tee sync

(一)功能

實現了BeanDefinitionRegistryPostProcessor接口的類,可以在覆寫的postProcessBeanDefinitionRegistry方法中向spring容器註冊bean

(二)實現

(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();
			}
		}
	}

  

springboot學習總結(十二)BeanDefinitionRegistryPostProcessor向spring容器中註冊bean