1. 程式人生 > 其它 >Spring原始碼-ImportSelector實現分析

Spring原始碼-ImportSelector實現分析

public interface ImportSelector {

    /**
     * Select and return the names of which class(es) should be imported based on
     * the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
     */
    String[] selectImports(AnnotationMetadata importingClassMetadata);

}

看一下該介面,註釋說明,實現該介面的selectImport則返回的String[]的 class字串 類將被註冊為@Configuration,即只要實現該介面返回的類將被注入Spring容器。@see ImportBeanDefinitionRegistrar則說明是使用 ImportBeanDefinitionRegistrar的registerBeanDefinitions方法進行注入。看一下其直接繼承的子類關係圖:

大致分為五類(後續分析其他原始碼需要):
Spring boot的自動裝配、測試、快取自動裝配、web相關。
Spring的aop相關的:@EnableTransactionManagement、@Async、@EnableCaching
下面以@EnableTransactionManagement主線進行梳理
只是從註釋看是通過ImportBeanDefinitionRegistrar進行注入的,但是今天梳理了一下,發現源頭還是從ApplicationContext的refresh模板模式方法(可以參見模板方法模式-簡單實現和Spring中的使用分析)開始。

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

模板方法第五步就是:

郭慕榮部落格園