springboot-spring-ioc-annotation源码学习

如果看完之后感觉内容较多可以参考总结版:https://blog.csdn.net/u010597819/article/details/87456084

springboot启动

  1. SpringApplication.run(Application.class, args)
public static ConfigurableApplicationContext run(Object[] sources, String[] args) {
	return new SpringApplication(sources).run(args);
}
  1. 创建SpringApplication
  2. SpringApplication初始化initialize
  3. Application.class放入sources中
  4. 判断是否web环境,commonClassCache,classloader中是否可以存在这些class
private static final String[] WEB_ENVIRONMENT_CLASSES = { "javax.servlet.Servlet",
	"org.springframework.web.context.ConfigurableWebApplicationContext" };
  1. 设置初始化对象(ApplicationContextInitializer 的实现)setInitializers,从工厂实例中获取实现getSpringFactoriesInstances即META-INF/spring.factories中
  2. 设置监听对象(ApplicationListener 的实现)setListeners,从工厂实例中获取实现getSpringFactoriesInstances即META-INF/spring.factories中
  3. 获取被设置主类入口:mainApplicationClass,遍历当前堆栈信息获取

SpringApplication启动run(args)

/**
 * Run the Spring application, creating and refreshing a new
 * {@link ApplicationContext}.
 * @param args the application arguments (usually passed from a Java main method)
 * @return a running {@link ApplicationContext}
 */
public ConfigurableApplicationContext run(String... args) {
	StopWatch stopWatch = new StopWatch();
	stopWatch.start();
	ConfigurableApplicationContext context = null;
	FailureAnalyzers analyzers = null;
	configureHeadlessProperty();
	SpringApplicationRunListeners listeners = getRunListeners(args);
	listeners.starting();
	try {
		ApplicationArguments applicationArguments = new DefaultApplicationArguments(
				args);
		ConfigurableEnvironment environment = prepareEnvironment(listeners,
				applicationArguments);
		Banner printedBanner = printBanner(environment);
		context = createApplicationContext();
		analyzers = new FailureAnalyzers(context);
		prepareContext(context, environment, listeners, applicationArguments,
				printedBanner);
		refreshContext(context);
		afterRefresh(context, applicationArguments);
		listeners.finished(context, null);
		stopWatch.stop();
		if (this.logStartupInfo) {
			new StartupInfoLogger(this.mainApplicationClass)
					.logStarted(getApplicationLog(), stopWatch);
		}
		return context;
	}
	catch (Throwable ex) {
		handleRunFailure(context, listeners, analyzers, ex);
		throw new IllegalStateException(ex);
	}
}
  1. 获取运行监听对象(ApplicationListener 的实现)setListeners,从工厂实例中获取实现getSpringFactoriesInstances即META-INF/spring.factories中
  2. 下面就是工厂实现类的配置
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.context.embedded.ServerPortInfoApplicationContextInitializer

# Application Listeners
org.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.liquibase.LiquibaseServiceLocatorApplicationListener,\
org.springframework.boot.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.logging.LoggingApplicationListener

# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor

# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ConnectorStartFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer

# FailureAnalysisReporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

  1. 启动监听listeners.starting();
  2. 创建应用参数对象ApplicationArguments
  3. prepareEnvironment准备环境
  4. 配置环境configureEnvironment
  5. 运行监听器EventPublishingRunListener广播环境准备完成消息,使用taskExecutor线程池,根据事件类型获取ApplicationListener监听器集合回调onApplicationEvent
  6. 打印环境信息printBanner
  7. createApplicationContext创建spring应用上下文,默认非web实现:AnnotationConfigApplicationContext,默认web环境实现AnnotationConfigEmbeddedWebApplicationContext
public AnnotationConfigApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}
  1. 创建AnnotatedBeanDefinitionReader
  1. registerAnnotationConfigProcessors注册处理对象
  2. 获取上下文中的beanFactory即DefaultListableBeanFactory
  3. beanFactory工厂设置依赖比较器,默认为AnnotationAwareOrderComparator
  4. beanFactory工厂设置Autowired候选解析器,默认为ContextAnnotationAutowireCandidateResolver
  5. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalConfigurationAnnotationProcessor:ConfigurationClassPostProcessor
  6. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalAutowiredAnnotationProcessor:AutowiredAnnotationBeanPostProcessor
  7. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalRequiredAnnotationProcessor:RequiredAnnotationBeanPostProcessor
  8. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalCommonAnnotationProcessor:CommonAnnotationBeanPostProcessor
  9. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalPersistenceAnnotationProcessor:PersistenceAnnotationBeanPostProcessor
  10. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalEventListenerProcessor:EventListenerMethodProcessor
  11. registerPostProcessor注册后置处理对象至BeanDefinitionRegistry internalEventListenerFactory:DefaultEventListenerFactory
  1. ClassPathBeanDefinitionScanner创建
  1. registerDefaultFilters注册默认过滤器:AnnotationTypeFilter(Component、ManagedBean、Named)
  2. 设置环境及ResourceLoader即应用上下文
  1. FailureAnalyzer失败分析接口绑定上下文中的beanFactory
  2. prepareContext准备上下文
  1. postProcessApplicationContext,启动时什么都不处理,因为resourceLoader,beanNameGenerator均为null
  2. applyInitializers应用初始化即ApplicationContextInitializer的工厂实现:ConfigurationWarningsApplicationContextInitializer、ContextIdApplicationContextInitializer、DelegatingApplicationContextInitializer、ServerPortInfoApplicationContextInitializer等初始化对象
  3. ConfigurationWarningsApplicationContextInitializer addBeanFactoryPostProcessor ,为应用上下文ApplicationContext添加ConfigurationWarningsPostProcessor后置处理
  4. ContextIdApplicationContextInitializer 为上下文设置id
  5. DelegatingApplicationContextInitializer 获取env环境中的context.initializer.classes配置的初始化类列表并初始化
  6. ServerPortInfoApplicationContextInitializer 上下文中添加EmbeddedServletContainerInitializedEvent事件类型的监听
  7. listeners.contextPrepared(context)广播上下文准备完成消息
  8. springApplicationArguments单例模式注册至工厂
  9. springBootBanner不为空的情况下同样单例模式注册至工厂
  10. load加载上下文:createBeanDefinitionLoader创建bean定义加载器,如果isGroovyPresent则加载,如果source是component则加载,默认没有什么都不做
  11. listeners.contextLoaded(context)监听广播上下文加载完成消息
  1. refreshContext刷新上下文
  1. 调用AbstractApplicationContext刷新上下文:spring XML 刷新上下文
  2. 调用钩子方法registerShutdownHook
  1. AbstractApplicationContext刷新(注解版本刷新流程)
  2. __prepareRefresh__刷新前准备动作AnnotationConfigApplicationContext清空metadataReaderFactory缓存并调用父类准备动作
  3. __obtainFreshBeanFactory__获取工厂,refreshBeanFactory刷新工厂GenericApplicationContext父类更新刷新标识并设置上下文id其他什么都不处理,GenericApplicationContext.getBeanFactory返回工厂(GenericApplicationContext上下文无参构造器中对beanFactory完成创建
  4. __prepareBeanFactory__准备beanFactory,设置StandardBeanExpressionResolver,添加ResourceEditorRegistrar、ApplicationContextAwareProcessor,添加忽略的依赖接口类型:EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware、ApplicationContextAware;注册已决定的依赖类型与对应的实现BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext;添加后置处理ApplicationListenerDetector;注册各种环境单例:environment、systemProperties、systemEnvironment
  5. __postProcessBeanFactory__后置操作,目前是什么都不处理
  6. __invokeBeanFactoryPostProcessors__调用后置处理
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
	...
}
  1. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors,调用委派对象的后置处理,入参为应用上下文的beanFactoryPostProcessors后置处理
  2. 如果入参后置处理对象为BeanDefinitionRegistryPostProcessor类型,回调 postProcessBeanDefinitionRegistry 后置处理,并添加至registryPostProcessors,否则放入regular集合中regularPostProcessors常规后置处理:Invoke BeanDefinitionRegistryPostProcessors first, if any.
  3. 从工厂中获取BeanDefinitionRegistryPostProcessor类型bean名称,并且判断是否存在优先级(PriorityOrdered),存在则排序后放入registryPostProcessors中,调用 postProcessBeanDefinitionRegistry 后置处理:First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
  1. 例如:ConfigurationClassPostProcessor处理逻辑
  2. ConfigurationClassPostProcessor回调postProcessBeanDefinitionRegistry
  3. processConfigBeanDefinitions,遍历当前工厂bean,如果存在Configuration注解或者Component、ComponentScan、Import、ImportResource注解,并且没有被解析处理过,如果开启了debug日志,则打印日志,否则继续
  4. 校验是否存在AnnotationMetadata并且Configuration注解对象,存在则添加至configCandidates候选配置集合中
  5. Return immediately if no @Configuration classes were found
  6. 如果localBeanNameGeneratorSet缓存中不存在该类名称生成器,则为componentScanBeanNameGenerator,importBeanNameGenerator设置为internalConfigurationBeanNameGenerator
  7. parser.parse解析每一个配置的bean(不仅仅是Configuration注解的bean):Parse each @Configuration class
  8. asSourceClass封装为SourceClass实例:Application入口为StandardAnnotationMetadata类型元数据(通过自省对象获取注解的类),其余为AnnotationMetadataReadingVisitor类型元数据,根据class类调用asSourceClass解析Configuration类:Recursively process the configuration class and its superclass hierarchy.
  9. doProcessConfigurationClass执行处理解析配置类:processMemberClasses解析处理所有内部类、接口对象;Process any @PropertySource annotations处理PropertySource注解对象;Process any @ComponentScan annotations处理所有扫描路径下的Component注解对象(第一次为Application对象,如果basePackages为空集合则设置为当前对象所属包路径);Process any @Import annotations处理所有import注解对象(importSelector返回选择要导入的对象集合遍历导入);Process any @ImportResource annotations;Process individual @Bean methods处理sourceClass的bean注解以及sourceClass方法中存在bean注解的bean定义;Process default methods on interfaces递归遍历处理(处理逻辑同上一步Process individual @Bean methods)Application所有父接口类定义与方法如果存在bean注解添加至Application的BeanMethod(方法注入的bean)元数据中(StandardAnnotationMetadata注解,并且包含Bean注解的方法);Process superclass, if any如果Application对象有父类则处理
  10. 配置类缓存在ConfigurationClassParser.configurationClasses等待加载bean定义
//processImports
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
		Collection importCandidates, boolean checkForCircularImports) throws IOException {
...
	for (SourceClass candidate : importCandidates) {
		if (candidate.isAssignable(ImportSelector.class)) {
			// Candidate class is an ImportSelector -> delegate to it to determine imports
			Class candidateClass = candidate.loadClass();
			ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
			ParserStrategyUtils.invokeAwareMethods(
					selector, this.environment, this.resourceLoader, this.registry);
			if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
				this.deferredImportSelectors.add(
						new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
			}
			else {
			//返回import要导入的class名称列表,递归处理解析导入
				String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
				Collection importSourceClasses = asSourceClasses(importClassNames);
				processImports(configClass, currentSourceClass, importSourceClasses, false);
			}
		}
		else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
			// Candidate class is an ImportBeanDefinitionRegistrar ->
			// delegate to it to register additional bean definitions
			Class candidateClass = candidate.loadClass();
			ImportBeanDefinitionRegistrar registrar =
					BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
			ParserStrategyUtils.invokeAwareMethods(
					registrar, this.environment, this.resourceLoader, this.registry);
					//将注解指定的ImportBeanDefinitionRegistrar绑定至configuration注解类封装的ConfigurationClass对象的importBeanDefinitionRegistrars属性中
					//在处理完当前configuration注解类的解析导入后,reader再读取ConfigurationClass的importBeanDefinitionRegistrars属性中的ImportBeanDefinitionRegistrar类列表
					//从ImportBeanDefinitionRegistrar中调用registerBeanDefinitions注入bean定义
			configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
		}
		else {
			// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
			// process it as an @Configuration class
			this.importStack.registerImport(
					currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
			processConfigurationClass(candidate.asConfigClass(configClass));
		}
	}
...
}
  1. reader.loadBeanDefinitions:ConfigurationClassBeanDefinitionReader加载bean定义loadBeanDefinitions loadBeanDefinitionsForBeanMethod,loadBeanDefinitionsFromImportedResources,MapperScannerRegistrar加载mapper,ImportBeanDefinitionRegistrar加载Import
private void loadBeanDefinitionsFromRegistrars(Map registrars) {
	for (Map.Entry entry : registrars.entrySet()) {
		entry.getKey().registerBeanDefinitions(entry.getValue(), this.registry);
	}
}
  1. postProcessBeanDefinitionRegistry处理完毕
  2. ConfigurationClassPostProcessor得postProcessBeanFactory处理类似,但多出下面两个步骤
  3. 注册ImportRegistry作为一个Bean至工厂来支持ImportAware通知动作,Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
  4. postProcessBeanFactory,显然不支持BeanDefinitionRegistryPostProcessor钩子方法,此时只需惰性地调用processConfigurationClasses,增强配置类enhanceConfigurationClasses,注册ImportAwareBeanPostProcessor至工厂后置处理
  1. 再次从工厂中获取BeanDefinitionRegistryPostProcessor类型bean名称,并且判断是否存在顺序(Ordered),存在则排序调用(排除之前回调过的) postProcessBeanDefinitionRegistry 后置处理:Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
  2. 调用剩余BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry回调函数:Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
  3. registryPostProcessors,regularPostProcessors,回调集合中的beanFactoryPostProcessor
  4. 从工厂中获取 BeanFactoryPostProcessor bean名称(排除之前回调过的),回调beanFactoryPostProcessor,同样的顺序,先调用PriorityOrdered类型的,其次Ordered类型的,最后普通的
  1. registerBeanPostProcessors
  2. initMessageSource
  3. initApplicationEventMulticaster
  4. onRefresh
  5. registerListeners
    注册监听:registerListeners(ApplicationListener),获取上下文中的监听或者工厂中该类型的bean进行注册。注册之前发布的消息缓存在上下文中的earlyApplicationEvents,将这些消息广播至当前注册的监听
  6. finishBeanFactoryInitialization:完成初始化:初始化非懒惰初始化的Bean
  7. finishRefresh
    发布上下文刷新完成事件:ContextRefreshedEvent
  8. resetCommonCaches
  9. 刷新完成
  10. afterRefresh SpringApplication刷新上下文后置动作
  11. listeners.finished SpringApplication监听器广播完成事件

上下文获取Bean ApplicationContext.getBean 同XML配置:spring XML 刷新上下文

你可能感兴趣的:(java,springboot,ioc,annotation)