1. 背景
在IOC前需搞清楚Spring容器,以及為什么需要Spring容器悍缠。
通常來說,使用容器運行組件耐量,除了提供一個組件運行環(huán)境之外,容器還提供了許多底層服務(wù)滤港。例如廊蜒,Servlet容器底層實現(xiàn)了TCP連接,解析HTTP協(xié)議等非常復(fù)雜的服務(wù)溅漾,如果沒有容器來提供這些服務(wù)山叮,我們就無法編寫像Servlet這樣代碼簡單,功能強大的組件添履。早期的JavaEE服務(wù)器提供的EJB容器最重要的功能就是通過聲明式事務(wù)服務(wù)屁倔,使得EJB組件的開發(fā)人員不必自己編寫冗長的事務(wù)處理代碼,所以極大地簡化了事務(wù)處理暮胧。
Spring的核心就是提供了一個IoC容器锐借,它可以管理所有輕量級的JavaBean組件,提供的底層服務(wù)包括組件的生命周期管理往衷、配置和組裝服務(wù)钞翔、AOP支持,以及建立在AOP基礎(chǔ)上的聲明式事務(wù)服務(wù)等席舍。
參考 IoC容器
2. 使用
2.1 基于XML
bean定義:
public class FirstBean {
public void hello() {
System.out.println("hello world");
}
}
XML定義:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean name="firstBean" class="com.cui.study.spring.FirstBean"/>
</beans>
類加載和使用:
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
FirstBean firstBean = context.getBean("firstBean", FirstBean.class);
firstBean.hello();
}
}
2.2 基于注解的方式
bean定義:
@Component
public class FirstBean {
public void hello() {
System.out.println("hello world");
}
}
類加載和使用:
@ComponentScan(value = "com.cui.study.spring")
public class Main {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
FirstBean firstBean = context.getBean("firstBean", FirstBean.class);
firstBean.hello();
}
}
3. 核心源碼解析
Spring 容器初始化核心流程在AbstractApplicationContext#refresh
方法中(版本為spring-context-5.3.23):
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
// 容器初始化前準(zhǔn)備布轿,如設(shè)置容器狀態(tài)、初始化監(jiān)聽器和事件列表等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 核心流程:初始化容器来颤,并解析xml汰扭、注解中的BeanDefinition列表
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 配置工廠類的標(biāo)準(zhǔn)化特征,如ClassLoader and post-processors.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 容器初始化福铅,并加載BeanDefinition后萝毛,修改容器
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
// 初始化 BeanFactoryPostProcessor 擴展點(容器擴展點),并執(zhí)行
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 創(chuàng)建并注冊 BeanPostProcessor(Bean擴展點)
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
// 初始化MessageSource滑黔,用于國際化
initMessageSource();
// Initialize event multicaster for this context.
// 初始化 ApplicationEventMulticaster
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//子容器擴展點珊泳,初始化其他特殊的bean
onRefresh();
// Check for listener beans and register them.
// 注冊 listener bean
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 核心流程:初始化所有剩余的非延遲初始化的單例bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 容器初始化結(jié)束,清理緩存拷沸,初始化并執(zhí)行LifecycleProcessor#onRefresh色查,發(fā)送ContextRefreshedEvent事件
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();
contextRefresh.end();
}
}
}
4. 基于XML方式的BeanDefinition
解析
基于XML的解析方式,在刷新容器時解析BeanDefinition撞芍,核心步驟主要分為以下幾個步驟:
- 容器刷新時解析
BeanDefinition
秧了; - 容器委托給
XmlBeanDefinitionReader
解析BeanDefinition
; -
XmlBeanDefinitionReader
將XML解析成Document
序无,并委托給BeanDefinitionDocumentReader
解析验毡; -
BeanDefinitionDocumentReader
處理<beans>標(biāo)簽衡创,解析出來的BeanDefinitionHolder
注冊到容器的beanDefinitionMap
對象中。<bean>標(biāo)簽解析過程委托給BeanDefinitionParserDelegate
晶通。
4.1BeanDefinitionParserDelegate
具體解析<bean>標(biāo)簽璃氢,返回BeanDefinitionHolder
。
4.1 容器刷新
加載BeanDefinition的入口在AbstractRefreshableApplicationContext#loadBeanDefinitions
中狮辽,具體邏輯在子類AbstractXmlApplicationContext
里實現(xiàn)一也。調(diào)用鏈路如下:
加載BeanDefinition委托給
BeanDefinitionReader#loadBeanDefinitions
方法,實現(xiàn)類為XmlBeanDefinitionReader
喉脖。
4.2 XmlBeanDefinitionReader解析過程
真正注冊
BeanDefinition
的操作在doLoadBeanDefinitions
中實現(xiàn)椰苟。
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
// try,忽略
// 將XML轉(zhuǎn)換成Document對象
Document doc = doLoadDocument(inputSource, resource);
// 注冊BeanDefinition树叽,并返回注冊BeanDefinition總數(shù)
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
// catch處理舆蝴,忽略
}
registerBeanDefinitions
中最后委托給BeanDefinitionDocumentReader#registerBeanDefinitions
。
4.3 BeanDefinitionDocumentReader解析過程
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 委托給BeanDefinitionDocumentReader的registerBeanDefinitions
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
在BeanDefinitionDocumentReader
中的調(diào)用鏈路如下:
parseBeanDefinitions
的實現(xiàn)細(xì)節(jié)如下:
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// Spring提供的默認(rèn)element解析题诵,包括import洁仗、alias、bean性锭、beans
parseDefaultElement(ele, delegate);
}
else {
// 自定義element解析(http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#xml-custom)
delegate.parseCustomElement(ele);
}
}
}
}
else {
delegate.parseCustomElement(root);
}
}
最終在parseDefaultElement
中解析XML中定義的import
京痢、alias
、bean
和beans
篷店。
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
主要看對bean標(biāo)簽的處理祭椰,在方法processBeanDefinition
中:
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 計算BeanDefinition,委托給BeanDefinitionParserDelegate實現(xiàn)真正的解析動作
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// 將BeanDefinition注冊到容器的beanDefinitionMap中
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
4.3.1 BeanDefinitionParserDelegate 解析過程
BeanDefinitionParserDelegate
中的實現(xiàn)邏輯如下:
核心邏輯在
parseBeanDefinitionElement
中疲陕,解析結(jié)果為GenericBeanDefinition
方淤,解析的元素可參考[Spring官方文檔]。(https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-autowired-annotation-qualifiers)
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
this.parseState.push(new BeanEntry(beanName));
String className = null;
if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
}
String parent = null;
if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
parent = ele.getAttribute(PARENT_ATTRIBUTE);
}
try {
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析bean屬性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// 解析meta標(biāo)簽
parseMetaElements(ele, bd);
// 解析lookup-method標(biāo)簽
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// 解析replaced-method標(biāo)簽
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// 解析constructor-arg標(biāo)簽
parseConstructorArgElements(ele, bd);
// 解析property標(biāo)簽
parsePropertyElements(ele, bd);
// 解析qualifier標(biāo)簽
parseQualifierElements(ele, bd);
bd.setResource(this.readerContext.getResource());
bd.setSource(extractSource(ele));
return bd;
}
catch (ClassNotFoundException ex) {
error("Bean class [" + className + "] not found", ele, ex);
}
catch (NoClassDefFoundError err) {
error("Class that bean class [" + className + "] depends on not found", ele, err);
}
catch (Throwable ex) {
error("Unexpected failure during bean definition parsing", ele, ex);
}
finally {
this.parseState.pop();
}
return null;
}
5. 基于Annotation方式的BeanDefinition
解析
基于Annotation的方式借助BeanFactoryPostProcessor
擴展類實現(xiàn)蹄殃。核心實現(xiàn)邏輯如下:
- 初始化
AnnotationConfigApplicationContext
時携茂,初始化AnnotatedBeanDefinitionReader
,在AnnotatedBeanDefinitionReader
中注冊ConfigurationClassPostProcessor
诅岩,實際解析BeanDefinition解析在ConfigurationClassPostProcessor
中完成讳苦; - 在
AbstractApplicationContext#refresh
初始化容器后,invokeBeanFactoryPostProcessors
方法中調(diào)用容器后置處理器吩谦; - 容器委托給
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
處理鸳谜,在委托類中調(diào)用postProcessor.postProcessBeanFactory
執(zhí)行容器后置處理器,其中包括ConfigurationClassPostProcessor
式廷,其優(yōu)先級最低咐扭。在ConfigurationClassPostProcessor
中處理配置類 -
ConfigurationClassPostProcessor
委托給ConfigurationClassParser
解析配置類列表中所有的BeanDefinition
;解析結(jié)束后,遞歸遍歷新解析BeanDefinition
中的配置類 - 在
ConfigurationClassParser
中遍歷配置類蝗肪,每個配置類委托給ComponentScanAnnotationParser
實現(xiàn)具體的BeanDefinition
解析動作 - 在
ComponentScanAnnotationParser
創(chuàng)建ClassPathBeanDefinitionScanner
袜爪,并計算待掃描路徑basePackages
,最后的解析動作委托給ClassPathBeanDefinitionScanner#doScan
處理 - 在
ClassPathBeanDefinitionScanner
找到所有配置類路徑范圍內(nèi)包含@Component
的類(@Service
/@Repository
/@Controller
是特殊的@Component
注解薛闪,也會被掃描)辛馆,創(chuàng)建ScannedGenericBeanDefinition
;委托AnnotationScopeMetadataResolver
解析@Scope
注解豁延;解析通用注解昙篙,包括@Lazy
、@Primary
术浪、@DependsOn
、@Role
寿酌、@Description
胰苏;檢測是否已注冊,如果未注冊則創(chuàng)建BeanDefinitionHolder
醇疼,如果未注冊完成注冊
5.1 AnnotationConfigApplicationContext
初始化過程
AnnotationConfigApplicationContext
初始化過程如下:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
// 初始化
this();
// 注冊入口配置類
register(componentClasses);
// 創(chuàng)建并刷新容器
refresh();
}
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 初始化AnnotatedBeanDefinitionReader硕并,注冊注解相關(guān)的處理器
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 初始化ClassPathBeanDefinitionScanner,注冊默認(rèn)注解過濾器秧荆,包括@Component
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
5.1.1 AnnotatedBeanDefinitionReader
創(chuàng)建過程
在BeanDefinition
解析中起到關(guān)鍵作用的功能是注冊ConfigurationClassPostProcessor
處理器:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注冊默認(rèn)處理器
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
// 調(diào)用本地方法
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
registerAnnotationConfigProcessors(registry, null);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
// 注冊ConfigurationClassPostProcessor處理器倔毙,基于@Component、@Service乙濒、@Repository陕赃、@Controller 注解的BeanDefinition解析主要依賴該處理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注冊AutowiredAnnotationBeanPostProcessor處理器,后面@Autowired注入的bean主要依賴該處理器
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
// 注冊CommonAnnotationBeanPostProcessor處理器颁股,后面@Resource注入的bean主要依賴該處理器處理
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
// 支持spring JPA
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 注冊EventListenerMethodProcessor么库,處理@EventListener注解的方法
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// 注冊DefaultEventListenerFactory,EventListener的默認(rèn)處理器
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
5.1.2 ClassPathBeanDefinitionScanner
創(chuàng)建過程
對解析BeanDefinition
起關(guān)鍵作用的功能是添加處理@Component
注解的AnnotationTypeFilter
過濾器甘有,核心代碼如下:
protected void registerDefaultFilters() {
// 在includeFilters中添加Component過濾器诉儒,解析BeanDefinition時使用此處理器過濾
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
}
catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
5.2 AbstractApplicationContext#refresh
容器刷新過程
在容器刷新主流程中,加載基于Annotation
的BeanDefinition
解析過程在invokeBeanFactoryPostProcessors(beanFactory);
中實現(xiàn):
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 解析動作委托給PostProcessorRegistrationDelegate處理
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
5.3 PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
容器創(chuàng)建后置處理器處理過程
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors
邏輯比較復(fù)雜亏掀,主要做了幾件事(邏輯只包括BeanDefinitionRegistry
容器忱反,非BeanDefinitionRegistry
較簡單,可自行從else
開始看):
- 執(zhí)行入?yún)氲?code>BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry方法(
BeanDefinitionRegistryPostProcessor
是BeanFactoryPostProcessor
的子類滤愕,增加了postProcessBeanDefinitionRegistry
擴展方法温算,用來注冊新的BeanDefinition
,注冊新的BeanDefinition
- 從容器中獲取實現(xiàn)了
PriorityOrdered
的BeanDefinitionRegistryPostProcessor间影,初始化米者,執(zhí)行起postProcessBeanDefinitionRegistry
方法注冊新的BeanDefinition
- 從容器中獲取實現(xiàn)了
Ordered
的BeanDefinitionRegistryPostProcessor,初始化,執(zhí)行起postProcessBeanDefinitionRegistry
方法注冊新的BeanDefinition
- 從容器中獲取實現(xiàn)了
Ordered
的BeanDefinitionRegistryPostProcessor蔓搞,初始化胰丁,執(zhí)行起postProcessBeanDefinitionRegistry
方法注冊新的BeanDefinition
- 從容器中獲取剩余的BeanDefinitionRegistryPostProcessor,初始化喂分,執(zhí)行起
postProcessBeanDefinitionRegistry
方法注冊新的BeanDefinition
- 從容器中獲取剩余的BeanDefinitionRegistryPostProcessor,初始化喂分,執(zhí)行起
- 執(zhí)行以上BeanDefinitionRegistryPostProcessor處理器的
postProcessBeanFactory
- 依次獲取并執(zhí)行實現(xiàn)了
PriorityOrdered
锦庸、Ordered
及其他的postProcessBeanFactory
方法
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 如果存在BeanDefinitionRegistryPostProcessor,執(zhí)行其postProcessBeanDefinitionRegistry方法蒲祈,修改BeanDefinition列表
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
// 獲取實現(xiàn)了PriorityOrdered的BeanDefinitionRegistryPostProcessor甘萧,并初始化(ConfigurationClassPostProcessor在此時被初始化)
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 執(zhí)行postProcessBeanDefinitionRegistry方法,修改容器BeanDefinition列表梆掸,BeanDefinition解析在這里處理
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
// 獲取實現(xiàn)了Ordered的BeanDefinitionRegistryPostProcessor處理器扬卷,初始化并執(zhí)行其invokeBeanDefinitionRegistryPostProcessors方法
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 循環(huán)獲取BeanDefinitionRegistryPostProcessor,初始化酸钦,執(zhí)行invokeBeanDefinitionRegistryPostProcessors方法怪得,直到無新的BeanDefinitionRegistryPostProcessor時結(jié)束
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 執(zhí)行后置處理器的postProcessBeanFactory方法,該方法需BeanDefinition注冊完調(diào)用
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// 獲取BeanFactoryPostProcessor卑硫,初始化并執(zhí)行后置處理器的postProcessBeanFactory方法徒恋,該方法需BeanDefinition注冊完調(diào)用
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}
5.4 ConfigurationClassPostProcessor
解析過程
ConfigurationClassPostProcessor
解析過程比較簡單:
- 從容器的
BeanDefinition
列表中獲取配置類 - 設(shè)置
BeanNameGenerator
- 創(chuàng)建
ConfigurationClassParser
,并委托給parser
解析 -
遞歸從解析結(jié)果中繼續(xù)獲取配置類欢伏,并委托給
ConfigurationClassParser
解析入挣,直到?jīng)]有配置類
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// 查找配置類,注解為@ Configuration硝拧、@Component径筏、@ComponentScan、@Import障陶、@ImportResource
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
// 排序操作
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
// 檢測是否存在自定義bean name生成策略匠璧,如果存在,創(chuàng)建并設(shè)置
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
// 創(chuàng)建ConfigurationClassParser咸这,具體解析委托給ConfigurationClassParser
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
// 遞歸調(diào)用夷恍,解析配置類,并從解析結(jié)果中篩選未解析的配置類媳维,繼續(xù)解析酿雪,直到無配置類
do {
StartupStep processConfig = this.applicationStartup.start("spring.context.config-classes.parse");
parser.parse(candidates);
parser.validate();
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
processConfig.tag("classCount", () -> String.valueOf(configClasses.size())).end();
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
5.5 ConfigurationClassParser
解析過程
parse
方法遍歷配置類,調(diào)用重載的parse(((AnnotatedBeanDefinition) bd).getMetadata()
完成解析侄刽。
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
this.deferredImportSelectorHandler.process();
}
parse
調(diào)用processConfigurationClass
解析指黎。
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
processConfigurationClass
實現(xiàn)如下:
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// 判斷 @Conditional 注解是否滿足條件
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
// 如果已經(jīng)解析過,且是@Import的類州丹,不重復(fù)解析
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
// 如果已經(jīng)解析過醋安,但不是@Import的杂彭,重復(fù)解析覆蓋
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
// 統(tǒng)一封裝成SourceClass處理
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 實際的解析動作
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
doProcessConfigurationClass
解析過程:
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
// 遞歸處理內(nèi)部類
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
// 處理@PropertySource注解,比較簡單吓揪,可見官網(wǎng)@PropertySource的用法
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 真正的解析動作委托給ComponentScanAnnotationParser#parse處理
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 遞歸遍歷已解析后的BeanDefinition
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
// 處理@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations
// 處理@ImportResource注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
// 處理方法@Bean注解
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
// 處理接口中的默認(rèn)方法實現(xiàn)中的 @Bean注解
processInterfaces(configClass, sourceClass);
// Process superclass, if any
// 處理父類
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
5.6 ComponentScanAnnotationParser
解析過程
ComponentScanAnnotationParser
解析 @ComponentScan
屬性亲怠,委托給 ClassPathBeanDefinitionScanner
解析。
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
for (AnnotationAttributes includeFilterAttributes : componentScan.getAnnotationArray("includeFilters")) {
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(includeFilterAttributes, this.environment,
this.resourceLoader, this.registry);
for (TypeFilter typeFilter : typeFilters) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes excludeFilterAttributes : componentScan.getAnnotationArray("excludeFilters")) {
List<TypeFilter> typeFilters = TypeFilterUtils.createTypeFiltersFor(excludeFilterAttributes, this.environment,
this.resourceLoader, this.registry);
for (TypeFilter typeFilter : typeFilters) {
scanner.addExcludeFilter(typeFilter);
}
}
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
5.7 ClassPathBeanDefinitionScanner
解析過程
解析BeanDefinition
柠辞,并注冊到spring容器团秽。
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 掃描所有`@Component`(包括`@Service`/`@Repository`/`@Controller`)注解類
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 處理 @Scope 注解
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
// 設(shè)置默認(rèn)參數(shù)
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析通用注解,包括@Lazy叭首,@Primary习勤,@DependsOn,@Role焙格,@Description注解
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 判斷是否已注冊图毕,如果未注冊,注冊到spring容器
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}