Spring Boot源码分析
1.核心:
SpringApplication.run(SpringbootdemoApplication.class, args);
内部
2.初始化:
new SpringApplication(primarySources)
其中重要的:
this.webApplicationType = this.deduceWebApplicationType();//根据是否存在"javax.servlet.Servlet", "org.springframework.web.context.ConfigurableWebApplicationContext"返回类型,这里返回WebApplicationType.SERVLET
this.setInitializers(this.getSpringFactoriesInstances(ApplicationContextInitializer.class));//设置初始化工厂类this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));//设置初始化监听this.mainApplicationClass = this.deduceMainApplicationClass();//设置含"main"的主类
其中
this.getSpringFactoriesInstances
方法从classpath的所有
"META-INF/spring.factories"
中加载方法参数对应的类(一个集合),返回其中每个类的实例的集合,这里
工厂类集合:
# Application Context Initializersorg.springframework.context.ApplicationContextInitializer=\org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\org.springframework.boot.context.ContextIdApplicationContextInitializer,\org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
监听集合:
# Application Listenersorg.springframework.context.ApplicationListener=\org.springframework.boot.ClearCachesApplicationListener,\org.springframework.boot.builder.ParentContextCloserApplicationListener,\org.springframework.boot.context.FileEncodingApplicationListener,\org.springframework.boot.context.config.AnsiOutputApplicationListener,\org.springframework.boot.context.config.ConfigFileApplicationListener,\org.springframework.boot.context.config.DelegatingApplicationListener,\org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\org.springframework.boot.context.logging.LoggingApplicationListener,\org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener
3.run方法:
(new SpringApplication(primarySources)).run(args)
其中重要的:
SpringApplicationRunListeners listeners = this.getRunListeners(args);
内部同样调用上面的
this.getSpringFactoriesInstances
方法加载并实例化
EventPublishingRunListener
使用其
EventPublishingRunListener(SpringApplication application, String[] args)
构造方法,第一个参数传递的是上面初始化好的SpringApplication,第二个参数是启动类传递的命令行参数数组
然后
listeners.starting();
将每个监听开启。
4.run方法中的Spring容器初始化部分
context = this.createApplicationContext();
方法,根据
this.webApplicationType
加载、实例化不同的BeanFactory实例,这里实例化
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext
这个实例化当中,AnnotationConfigServletWebServerApplicationContext最终继承GenericApplicationContext,该父类构造方法中:
public GenericApplicationContext() { this.customClassLoader = false; this.refreshed = new AtomicBoolean(); this.beanFactory = new DefaultListableBeanFactory();}
实例化了一个DefaultListableBeanFactory,它是Spring和核心BeanFactory类,将完成下面重要的Spring容器初始化过程。
但这里的Spring初始化入口是AnnotationConfigServletWebServerApplicationContext自己的构造方法:
public AnnotationConfigServletWebServerApplicationContext() { this.annotatedClasses = new LinkedHashSet(); this.reader = new AnnotatedBeanDefinitionReader(this); this.scanner = new ClassPathBeanDefinitionScanner(this);}
加粗方法内部,执行的是AnnotatedBeanDefinitionReader类的构造方法:
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { this.beanNameGenerator = new AnnotationBeanNameGenerator(); this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(); 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, (ResourceLoader)null); AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}
这里的BeanDefinitionRegistry就是实例化AnnotatedBeanDefinitionReader时传入的AnnotationConfigServletWebServerApplicationContext实例,它最终(通过GenericApplicationContext)实现了BeanDefinitionRegistry.
加粗方法进入AnnotationConfigUtils的registerAnnotationConfigProcessors方法:
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); RootBeanDefinition def; if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalConfigurationAnnotationProcessor")) {def = new RootBeanDefinition(ConfigurationClassPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalConfigurationAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalAutowiredAnnotationProcessor")) { def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalAutowiredAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.annotation.internalRequiredAnnotationProcessor")) { def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor")); } if (jsr250Present && !registry.containsBeanDefinition("org.springframework.context.annotation.internalCommonAnnotationProcessor")) { def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalCommonAnnotationProcessor")); } if (jpaPresent && !registry.containsBeanDefinition("org.springframework.context.annotation.internalPersistenceAnnotationProcessor")) { def = new RootBeanDefinition(); try { def.setBeanClass(ClassUtils.forName("org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", AnnotationConfigUtils.class.getClassLoader())); } catch (ClassNotFoundException var6) { throw new IllegalStateException("Cannot load optional framework class: org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor", var6); } def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.annotation.internalPersistenceAnnotationProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerProcessor")) { def = new RootBeanDefinition(EventListenerMethodProcessor.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerProcessor")); } if (!registry.containsBeanDefinition("org.springframework.context.event.internalEventListenerFactory")) { def = new RootBeanDefinition(DefaultEventListenerFactory.class); def.setSource(source); beanDefs.add(registerPostProcessor(registry, def, "org.springframework.context.event.internalEventListenerFactory")); } return beanDefs;}
该方法创建了后处理器Bean的BeanDefinition,并使用BeanDefinitionRegistry注册了一些后处理器,比如:
registerPostProcessor(registry, def, "org.springframework.context.annotation.internalRequiredAnnotationProcessor")
在这个registerPostProcessor方法中:
private static BeanDefinitionHolder registerPostProcessor(BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) { definition.setRole(2); registry.registerBeanDefinition(beanName, definition); return new BeanDefinitionHolder(definition, beanName);}
加粗方法最终进入GenericApplicationContext中实例化的DefaultListableBeanFactory进行BeanDefinition的注册,这里是注册后处理器Bean,以下就是DefaultListableBeanFactory中重要的BeanDefinition注册方法:
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition)beanDefinition).validate(); } catch (BeanDefinitionValidationException var9) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var9); } } BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!this.isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + existingDefinition + "] bound."); } if (existingDefinition.getRole() < beanDefinition.getRole()) { if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (this.hasBeanCreationStarted()) { Map var4 = this.beanDefinitionMap; synchronized(this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); List<String> updatedDefinitions = new ArrayList(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set<String> updatedSingletons = new LinkedHashSet(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else {this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || this.containsSingleton(beanName)) { this.resetBeanDefinition(beanName); } }
该方法最终在beanDefinitionMap中存储了7个后处理器:
这里的context就是创建的AnnotationConfigServletWebServerApplicationContext,内部的BeanFactory就是其内部实例化的DefaultListableBeanFactory,beanDefinitionMap就在它内部。
这个方法在后面我们自定义Bean的注册中会反复使用。
5.下一个重要方法:
this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
该方法:
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment, SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) { context.setEnvironment(environment); this.postProcessApplicationContext(context); this.applyInitializers(context); listeners.contextPrepared(context); if (this.logStartupInfo) { this.logStartupInfo(context.getParent() == null); this.logStartupProfileInfo(context); } context.getBeanFactory().registerSingleton("springApplicationArguments", applicationArguments); if (printedBanner != null) { context.getBeanFactory().registerSingleton("springBootBanner", printedBanner); } Set<Object> sources = this.getAllSources(); Assert.notEmpty(sources, "Sources must not be empty");this.load(context, sources.toArray(new Object[0])); listeners.contextLoaded(context);}
中,sources代表初始化资源,这里是SpringApplication实例化时传入的主类SpringbootdemoApplication,然后带着资源进入load方法:
protected void load(ApplicationContext context, Object[] sources) { if (logger.isDebugEnabled()) { logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources)); } BeanDefinitionLoader loader = this.createBeanDefinitionLoader(this.getBeanDefinitionRegistry(context), sources); if (this.beanNameGenerator != null) { loader.setBeanNameGenerator(this.beanNameGenerator); } if (this.resourceLoader != null) { loader.setResourceLoader(this.resourceLoader); } if (this.environment != null) { loader.setEnvironment(this.environment); } loader.load();}
第一个加粗方法使用AnnotationConfigServletWebServerApplicationContext(实现了BeanDefinitionRegistry)和资源创建一个BeanDefinitionLoader:
BeanDefinitionLoader(BeanDefinitionRegistry registry, Object... sources) { Assert.notNull(registry, "Registry must not be null"); Assert.notEmpty(sources, "Sources must not be empty"); this.sources = sources;this.annotatedReader = new AnnotatedBeanDefinitionReader(registry); this.xmlReader = new XmlBeanDefinitionReader(registry); if (this.isGroovyPresent()) { this.groovyReader = new GroovyBeanDefinitionReader(registry); } this.scanner = new ClassPathBeanDefinitionScanner(registry); this.scanner.addExcludeFilter(new BeanDefinitionLoader.ClassExcludeFilter(sources));}
第一句加粗和上面一样,使用registry创建了一个AnnotatedBeanDefinitionReader,内部还是DefaultListableBeanFactory的那7个后处理器
第二句加粗,创建了
出了BeanDefinitionLoader的整个创建后,接着上面SpringApplication的load方法,使用刚刚创建的BeanDefinitionLoader的load方法,该方法最终调用其重载方法:
private int load(Class<?> source) { if (this.isGroovyPresent() && BeanDefinitionLoader.GroovyBeanDefinitionSource.class.isAssignableFrom(source)) { BeanDefinitionLoader.GroovyBeanDefinitionSource loader = (BeanDefinitionLoader.GroovyBeanDefinitionSource)BeanUtils.instantiateClass(source, BeanDefinitionLoader.GroovyBeanDefinitionSource.class); this.load(loader); } if (this.isComponent(source)) {this.annotatedReader.register(new Class[]{source}); return 1; } else { return 0; }}
其中的资源就是主类SpringbootdemoApplication,这个方法最终进入AnnotatedBeanDefinitionReader的方法:
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name, @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); if (!this.conditionEvaluator.shouldSkip(abd.getMetadata())) { abd.setInstanceSupplier(instanceSupplier); ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); abd.setScope(scopeMetadata.getScopeName()); String beanName = name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry); AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); int var10; int var11; if (qualifiers != null) { Class[] var9 = qualifiers; var10 = qualifiers.length; for(var11 = 0; var11 < var10; ++var11) { Class<? extends Annotation> qualifier = var9[var11]; if (Primary.class == qualifier) { abd.setPrimary(true); } else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } BeanDefinitionCustomizer[] var13 = definitionCustomizers; var10 = definitionCustomizers.length; for(var11 = 0; var11 < var10; ++var11) { BeanDefinitionCustomizer customizer = var13[var11]; customizer.customize(abd); } BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }}
这里的最后,将主类处理成BeanDefinitionHolder,和registry一起传入,进入BeanDefinitionReaderUtils:
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { String beanName = definitionHolder.getBeanName();registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); String[] aliases = definitionHolder.getAliases(); if (aliases != null) { String[] var4 = aliases; int var5 = aliases.length; for(int var6 = 0; var6 < var5; ++var6) { String alias = var4[var6]; registry.registerAlias(beanName, alias); } } }
加粗一句和上面的分析是一样的,最终使用将主类实例注册到DefaultListableBeanFactory的beanDefinitionMap中。
6.下一个重要的方法:
this.refreshContext(context);
最终将我们的AnnotationConfigServletWebServerApplicationContext强转成底层基类
AbstractApplicationContext
调用其refresh方法:
public void refresh() throws BeansException, IllegalStateException { Object var1 = this.startupShutdownMonitor; synchronized(this.startupShutdownMonitor) { this.prepareRefresh();ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory(); this.prepareBeanFactory(beanFactory); try { this.postProcessBeanFactory(beanFactory);this.invokeBeanFactoryPostProcessors(beanFactory); this.registerBeanPostProcessors(beanFactory); this.initMessageSource(); this.initApplicationEventMulticaster(); this.onRefresh(); this.registerListeners(); this.finishBeanFactoryInitialization(beanFactory); this.finishRefresh(); } catch (BeansException var9) { if (this.logger.isWarnEnabled()) { this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9); } this.destroyBeans(); this.cancelRefresh(var9); throw var9; } finally { this.resetCommonCaches(); } }}
这里的beanFactory仍然是AnnotationConfigServletWebServerApplicationContext内部创建的DefaultListableBeanFactory,且当前一共有包括主类和后处理器在内的8个BeanDefinition.这里进入invokeBeanFactoryPostProcessors方法,该方法最终进入PostProcessorRegistrationDelegate类的静态方法:
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet(); ArrayList regularPostProcessors; ArrayList registryProcessors; int var9; ArrayList currentRegistryProcessors; String[] postProcessorNames; if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory; regularPostProcessors = new ArrayList(); registryProcessors = new ArrayList(); Iterator var6 = beanFactoryPostProcessors.iterator(); while(var6.hasNext()) { BeanFactoryPostProcessor postProcessor = (BeanFactoryPostProcessor)var6.next(); if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor)postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } currentRegistryProcessors = new ArrayList(); postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); String[] var16 = postProcessorNames; var9 = postProcessorNames.length; int var10; String ppName; for(var10 = 0; var10 < var9; ++var10) { ppName = var16[var10]; if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors);invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); var16 = postProcessorNames; var9 = postProcessorNames.length; for(var10 = 0; var10 < var9; ++var10) { ppName = var16[var10]; 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); currentRegistryProcessors.clear(); boolean reiterate = true; while(reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); String[] var19 = postProcessorNames; var10 = postProcessorNames.length; for(int var26 = 0; var26 < var10; ++var26) { String ppName = var19[var26]; 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); currentRegistryProcessors.clear(); } invokeBeanFactoryPostProcessors((Collection)registryProcessors, (ConfigurableListableBeanFactory)beanFactory); invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory); } else { invokeBeanFactoryPostProcessors((Collection)beanFactoryPostProcessors, (ConfigurableListableBeanFactory)beanFactory); } String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); regularPostProcessors = new ArrayList(); registryProcessors = new ArrayList(); currentRegistryProcessors = new ArrayList(); postProcessorNames = postProcessorNames; int var20 = postProcessorNames.length; String ppName; for(var9 = 0; var9 < var20; ++var9) { ppName = postProcessorNames[var9]; if (!processedBeans.contains(ppName)) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { regularPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { registryProcessors.add(ppName); } else { currentRegistryProcessors.add(ppName); } } } sortPostProcessors(regularPostProcessors, beanFactory); invokeBeanFactoryPostProcessors((Collection)regularPostProcessors, (ConfigurableListableBeanFactory)beanFactory); List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList(); Iterator var21 = registryProcessors.iterator(); while(var21.hasNext()) { String postProcessorName = (String)var21.next(); orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors((Collection)orderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory); List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList(); Iterator var24 = currentRegistryProcessors.iterator(); while(var24.hasNext()) { ppName = (String)var24.next(); nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors((Collection)nonOrderedPostProcessors, (ConfigurableListableBeanFactory)beanFactory); beanFactory.clearMetadataCache();}
该方法传入三个后处理器,重要的一个是ConfigurationClassPostProcessor,用来解析主类,将其所在包内所有类的注解配置解析,创建、注册需要的Bean,这里执行加粗方法:
private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { Iterator var2 = postProcessors.iterator(); while(var2.hasNext()) { BeanDefinitionRegistryPostProcessor postProcessor = (BeanDefinitionRegistryPostProcessor)var2.next();postProcessor.postProcessBeanDefinitionRegistry(registry); } }
上面加粗方法,其中的ConfigurationClassPostProcessor执行的是其下面的方法:
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList();String[] candidateNames = registry.getBeanDefinitionNames(); String[] var4 = candidateNames; int var5 = candidateNames.length; for(int var6 = 0; var6 < var5; ++var6) { String beanName = var4[var6];BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (!ConfigurationClassUtils.isFullConfigurationClass(beanDef) && !ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } else if (this.logger.isDebugEnabled()) { this.logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } if (!configCandidates.isEmpty()) { configCandidates.sort((bd1, bd2) -> { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return Integer.compare(i1, i2); }); SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) {sbr = (SingletonBeanRegistry)registry; if (!this.localBeanNameGeneratorSet) {BeanNameGenerator generator = (BeanNameGenerator)sbr.getSingleton("org.springframework.context.annotation.internalConfigurationBeanNameGenerator"); if (generator != null) {this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); } ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); Set<BeanDefinitionHolder> candidates = new LinkedHashSet(configCandidates); HashSet alreadyParsed = new HashSet(configCandidates.size()); do {parser.parse(candidates); parser.validate(); Set<ConfigurationClass> configClasses = new LinkedHashSet(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); 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); candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set<String> oldCandidateNames = new HashSet(Arrays.asList(candidateNames)); Set<String> alreadyParsedClasses = new HashSet(); Iterator var12 = alreadyParsed.iterator(); while(var12.hasNext()) { ConfigurationClass configurationClass = (ConfigurationClass)var12.next(); alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); } String[] var23 = newCandidateNames; int var24 = newCandidateNames.length; for(int var14 = 0; var14 < var24; ++var14) { String candidateName = var23[var14]; 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()); if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); } if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { ((CachingMetadataReaderFactory)this.metadataReaderFactory).clearCache(); } }}
上面的
parser.parse(candidates);
是ConfigurationClassParser的方法,
进入其
@Nullableprotected final ConfigurationClassParser.SourceClass doProcessConfigurationClass(ConfigurationClass configClass, ConfigurationClassParser.SourceClass sourceClass) throws IOException { this.processMemberClasses(configClass, sourceClass); Iterator var3 = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), PropertySources.class, PropertySource.class).iterator(); AnnotationAttributes importResource; while(var3.hasNext()) { importResource = (AnnotationAttributes)var3.next(); if (this.environment instanceof ConfigurableEnvironment) { this.processPropertySource(importResource); } else { this.logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() + "]. Reason: Environment must implement ConfigurableEnvironment"); } } Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); if (!componentScans.isEmpty() && !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) { Iterator var13 = componentScans.iterator(); while(var13.hasNext()) { AnnotationAttributes componentScan = (AnnotationAttributes)var13.next();Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); Iterator var7 = scannedBeanDefinitions.iterator(); while(var7.hasNext()) { BeanDefinitionHolder holder = (BeanDefinitionHolder)var7.next(); BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); if (bdCand == null) { bdCand = holder.getBeanDefinition(); } if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { this.parse(bdCand.getBeanClassName(), holder.getBeanName()); } } } } this.processImports(configClass, sourceClass, this.getImports(sourceClass), true); importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class); if (importResource != null) { String[] resources = importResource.getStringArray("locations"); Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader"); String[] var19 = resources; int var21 = resources.length; for(int var22 = 0; var22 < var21; ++var22) { String resource = var19[var22]; String resolvedResource = this.environment.resolveRequiredPlaceholders(resource); configClass.addImportedResource(resolvedResource, readerClass); } } Set<MethodMetadata> beanMethods = this.retrieveBeanMethodMetadata(sourceClass); Iterator var17 = beanMethods.iterator(); while(var17.hasNext()) { MethodMetadata methodMetadata = (MethodMetadata)var17.next(); configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); } this.processInterfaces(configClass, sourceClass); if (sourceClass.getMetadata().hasSuperClass()) { String superclass = sourceClass.getMetadata().getSuperClassName(); if (superclass != null && !superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) { this.knownSuperclasses.put(superclass, configClass); return sourceClass.getSuperClass(); } } return null;}
方法,加粗方法进入ComponentScanAnnotationParser的parse方法,该方法创建了ClassPathBeanDefinitionScanner实例,进入其doScan方法:
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet(); String[] var3 = basePackages; int var4 = basePackages.length; for(int var5 = 0; var5 < var4; ++var5) { String basePackage = var3[var5]; Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage); Iterator var8 = candidates.iterator(); while(var8.hasNext()) { BeanDefinition candidate = (BeanDefinition)var8.next(); ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate); candidate.setScope(scopeMetadata.getScopeName()); String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate); } if (this.checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); beanDefinitions.add(definitionHolder); this.registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions;}
这里的basePackages是上层解析主类解析出来的该类包名,这个方法内部又经过ClassPathScanningCandidateComponentProvider的scanCandidateComponents方法:
private Set<BeanDefinition> scanCandidateComponents(String basePackage) { LinkedHashSet candidates = new LinkedHashSet(); try {String packageSearchPath = "classpath*:" + this.resolveBasePackage(basePackage) + '/' + this.resourcePattern; Resource[] resources = this.getResourcePatternResolver().getResources(packageSearchPath); boolean traceEnabled = this.logger.isTraceEnabled(); boolean debugEnabled = this.logger.isDebugEnabled();Resource[] var7 = resources; int var8 = resources.length; for(int var9 = 0; var9 < var8; ++var9) {Resource resource = var7[var9]; if (traceEnabled) { this.logger.trace("Scanning " + resource); } if (resource.isReadable()) { try { MetadataReader metadataReader = this.getMetadataReaderFactory().getMetadataReader(resource); if (this.isCandidateComponent(metadataReader)) {ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setResource(resource); sbd.setSource(resource); if (this.isCandidateComponent((AnnotatedBeanDefinition)sbd)) { if (debugEnabled) { this.logger.debug("Identified candidate component class: " + resource); } candidates.add(sbd); } else if (debugEnabled) { this.logger.debug("Ignored because not a concrete top-level class: " + resource); } } else if (traceEnabled) { this.logger.trace("Ignored because not matching any filter: " + resource); } } catch (Throwable var13) { throw new BeanDefinitionStoreException("Failed to read candidate component class: " + resource, var13); } } else if (traceEnabled) { this.logger.trace("Ignored because not readable: " + resource); } } return candidates; } catch (IOException var14) { throw new BeanDefinitionStoreException("I/O failure during classpath scanning", var14); }}
这里扫描到了主类包下所有我们自定义的类:
最终将要创建的Bean全部处理成BeanDefinition注册到registry,这里经过多次递归上面的几个主要类的处理过程,最终创建所有194个Bean:
处理完所有的Bean后,PostProcessorRegistrationDelegate的方法继续执行,执行了其他几个后处理器,最后回到AbstractApplicationContext的refresh方法,最后回到SpringApplication的
this.refreshContext(context);
方法,最终完成所有方法,SpringBoot启动完成。
一定要断点调试,直接看源码臆想过程会出错!!
基础知识地址:
https://www.cnblogs.com/xiaoxi/p/6392154.html
https://blog.csdn.net/masterchiefcc/article/details/80358977
转载于:https://www.cnblogs.com/free-wings/p/10005763.html
Spring Boot源码分析相关推荐
- 精尽Spring Boot源码分析 - 内嵌Tomcat容器的实现
概述 我们知道 Spring Boot 能够创建独立的 Spring 应用,内部嵌入 Tomcat 容器(Jetty.Undertow),让我们的 jar 无需放入 Servlet 容器就能直接运行. ...
- spring boot 源码分析(七) 事件机制 之 SpringApplicationEvent
2019独角兽企业重金招聘Python工程师标准>>> 一.前言 前面的文章我们讲解了一下spring boot配置文件加载的相关源码分析,下面我们将从源码角度讲解一下spring ...
- spring boot源码分析之SpringApplication
spring boot提供了sample程序,学习spring boot之前先跑一个最简单的示例: /** Copyright 2012-2016 the original author or aut ...
- 实战:Spring Boot源码解读与原理分析
承载着作者的厚望,掘金爆火小册同名读物<Spring Boot源码解读与原理剖析>正式出书! 本书前身是掘金社区销量TOP的小册--<Spring Boot源码解读与原理剖析> ...
- spring boot 源码解析23-actuate使用及EndPoint解析
前言 spring boot 中有个很诱人的组件–actuator,可以对spring boot应用做监控,只需在pom文件中加入如下配置即可: <dependency><group ...
- 【赠书福利】掘金爆火小册同名《Spring Boot源码解读与原理剖析》正式出书了!...
关注我们丨文末赠书 承载着作者的厚望,掘金爆火小册同名读物<Spring Boot源码解读与原理剖析>正式出书! 本书前身是掘金社区销量TOP的小册--<Spring Boot源码解 ...
- Spring Cloud源码分析(二)Ribbon(续)
因文章长度限制,故分为两篇.上一篇:<Spring Cloud源码分析(二)Ribbon> 负载均衡策略 通过上一篇对Ribbon的源码解读,我们已经对Ribbon实现的负载均衡器以及其中 ...
- Spring AOP 源码分析 - 拦截器链的执行过程
1.简介 本篇文章是 AOP 源码分析系列文章的最后一篇文章,在前面的两篇文章中,我分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在我们的得 ...
- Spring AOP 源码分析 - 创建代理对象
1.简介 在上一篇文章中,我分析了 Spring 是如何为目标 bean 筛选合适的通知器的.现在通知器选好了,接下来就要通过代理的方式将通知器(Advisor)所持有的通知(Advice)织入到 b ...
- Spring AOP 源码分析 - 筛选合适的通知器
1.简介 从本篇文章开始,我将会对 Spring AOP 部分的源码进行分析.本文是 Spring AOP 源码分析系列文章的第二篇,本文主要分析 Spring AOP 是如何为目标 bean 筛选出 ...
最新文章
- Android系列讲座(2):为TextView组件加上边框
- 0xc0000225无法进系统_冷却塔进风格栅结冰主要原因及对策
- 牛!这位斯坦福PhD新生的论文被引数:接近4万
- 什么是UUID及其实现代码
- 12c expdp ORA-31623 -又遇到BUG
- 4-1 复数类的运算符重载
- Fibonacci数列的幂和
- 确认! Python夺冠,Java“被迫”退出竞争舞台,网友:崩溃!
- 使用valgrind检查内存问题
- Oracle11默认用户名和密码
- java里面数字四舍五入,Java数字的四舍五入
- Python多线程好玩弹窗代码
- 吊炸天——74款APP完整源码
- Python excel转txt文件
- cpu压力测试 Android,测试CPU和GPU性能压力(StressMyPC)
- 计算机管理员权限win8,怎样获取win8.1超级管理员权限
- 微信小程序富文本编辑器
- kodi资源_Kodi——支持全平台的看片神器
- 笔记本右侧键盘数字打不出来
- MacOS / Vmware Fusion无法连接虚拟设备sata0:1,因为主机上没有相应设备
热门文章
- linux中crontab的用法
- r语言把多个图合并在一张图_R语言绘图 | 折线图画法,如何画出你满意的图?
- Linux主要的系统目录及其简单描述
- matlab 删掉空行,在MATLAB中使用XLSWRITE:如何删除空单元格?
- Hive cube,roll up入门案例
- openresty入门 方法及指令
- Linux开发_printf打印无消息或末尾带“#“or“%“
- 使用Opencv绘制灰度直方图/对比
- 什么是服务的熔断降级
- 实例化vue发生了什么?(详解vue生命周期)