『SpringBoot 源码分析』run() 方法执行流程:(2)刷新应用上下文-准备阶段
 
- 基于 2.2.9.RELEASE
 - 问题:当方法进行了注释标记之后,springboot 又是怎么注入到容器中并创建类呢?
 
 
- 首先创建测试主程序
 
 
package com.lagou;
@SpringBootApplication
public class SpringBootMytestApplication{
	public static void main(String[] args) {
		SpringApplication.run(SpringBootMytestApplication.class, args);
	}
}
 
- 创建测试 Controller
 
 
package com.lagou.controller;
@RestController
public class TestController {
	@RequestMapping("/test")
	public String test(){
		System.out.println("源码环境构建成功...");
		return "源码环境构建成功";
	}
}
 
准备阶段
 
- 当准备完成应用上下文环境,以及应用上下文以后,需要为应用上下文做个准备阶段,简单来说其实就是要配置应用上下文,把需要的类装配上
 
 
public class SpringApplication {
	...
	public ConfigurableApplicationContext run(String... args) {
		...
		try {
			
			ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
			
			ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
			
			configureIgnoreBeanInfo(environment);
			
			Banner printedBanner = printBanner(environment);
			
			context = createApplicationContext();
			
			exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
					new Class[] { ConfigurableApplicationContext.class }, context);
			
			prepareContext(context, environment, listeners, applicationArguments, printedBanner);
			...
		}
		catch (Throwable ex) {
			...
		}
		...
	}
}
 
- 在对应用上下文进行处理时,主要执行了下面几步的装配
 
 
- 把上下文环境设置到应用上下文中
 - 执行容器后置处理
 - 把应用上下文交给 SpringApplication 初始化收集的 org.springframework.context.ApplicationContextInitializer 所有实现类进行初始化工作
 - 利用 org.springframework.boot.context.event.EventPublishingRunListener 向 org.springframework.context.ApplicationListener 发布容器准备好事件
 
 
public class SpringApplication {
	...
	
	private void  prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		
		context.setEnvironment(environment);
		
		postProcessApplicationContext(context);
		
		applyInitializers(context); 
		
		listeners.contextPrepared(context);
		...
	}
}
 
- 执行容器后置处理:其实只是往 BeanFactory 添加了基础的转换器
 
 
public class SpringApplication {
	private BeanNameGenerator beanNameGenerator;
	private ResourceLoader resourceLoader;
	private boolean addConversionService = true;
	...
	protected void postProcessApplicationContext(ConfigurableApplicationContext context) {
		if (this.beanNameGenerator != null) {
			context.getBeanFactory().registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR,
					this.beanNameGenerator);
		}
		if (this.resourceLoader != null) {
			if (context instanceof GenericApplicationContext) {
				((GenericApplicationContext) context).setResourceLoader(this.resourceLoader);
			}
			if (context instanceof DefaultResourceLoader) {
				((DefaultResourceLoader) context).setClassLoader(this.resourceLoader.getClassLoader());
			}
		}
		
		if (this.addConversionService) { 
			
			context.getBeanFactory().setConversionService(ApplicationConversionService.getSharedInstance());
		}
	}
}
 
- 执行一些初始化器:就是遍历 org.springframework.context.ApplicationContextInitializer 执行 initialize() 方法
 
 
public class SpringApplication {
	...
	protected void applyInitializers(ConfigurableApplicationContext context) {
		for (ApplicationContextInitializer initializer : getInitializers()) {
			Class<?> requiredType = GenericTypeResolver.resolveTypeArgument(initializer.getClass(),
					ApplicationContextInitializer.class);
			Assert.isInstanceOf(requiredType, context, "Unable to call initializer.");
			initializer.initialize(context);
		}
	}
}
 
- 向各个监听器发送容器已经准备好的事件:就是 org.springframework.boot.context.event.EventPublishingRunListener 向 org.springframework.context.ApplicationListener 发布容器准备好事件
 
 
public class SpringApplication {
	...
	
	void contextPrepared(ConfigurableApplicationContext context) {
		for (SpringApplicationRunListener listener : this.listeners) {
			listener.contextPrepared(context);
		}
	}
}
 
- 发布完监听之后,从上下文中获取 IOC 工厂,并设置允许 bean 定义被覆盖参数
 
 
public class SpringApplication {
	...
	
	private void  prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		
		context.setEnvironment(environment);
		
		postProcessApplicationContext(context);
		
		applyInitializers(context); 
		
		listeners.contextPrepared(context);
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}
		
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		
		beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
		if (printedBanner != null) {
			
			beanFactory.registerSingleton("springBootBanner", printedBanner);
		}
		
		if (beanFactory instanceof DefaultListableBeanFactory) {
			((DefaultListableBeanFactory) beanFactory)
					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		...
	}
}
 
- 然后加载启动类,并将启动类注入到容器当中,然后发布容器已加载事件
 
 
public class SpringApplication {
	...
	
	private void  prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
			SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
		
		context.setEnvironment(environment);
		
		postProcessApplicationContext(context);
		
		applyInitializers(context); 
		
		listeners.contextPrepared(context);
		if (this.logStartupInfo) {
			logStartupInfo(context.getParent() == null);
			logStartupProfileInfo(context);
		}
		
		ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		
		beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
		if (printedBanner != null) {
			
			beanFactory.registerSingleton("springBootBanner", printedBanner);
		}
		
		if (beanFactory instanceof DefaultListableBeanFactory) {
			((DefaultListableBeanFactory) beanFactory)
					.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.lazyInitialization) { 
			context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
		}
		
		Set<Object> sources = getAllSources();
		Assert.notEmpty(sources, "Sources must not be empty");
		
		load(context, sources.toArray(new Object[0]));
		
		listeners.contextLoaded(context);
	}
}
 
- 其中将启动类注入到容器当中是比较关键的一步,首先先把 ApplicationContext 转换成 BeanDefinitionRegistry,然后创建 bean 定义加载器
 
 
public class SpringApplication {
	...
	protected void load(ApplicationContext context, Object[] sources) {
		if (logger.isDebugEnabled()) {
			logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
		}
		
		BeanDefinitionLoader loader = createBeanDefinitionLoader(getBeanDefinitionRegistry(context), sources);
		...
	}
	
	private BeanDefinitionRegistry getBeanDefinitionRegistry(ApplicationContext context) {
		
		if (context instanceof BeanDefinitionRegistry) {
			return (BeanDefinitionRegistry) context;
		}
		if (context instanceof AbstractApplicationContext) {
			return (BeanDefinitionRegistry) ((AbstractApplicationContext) context).getBeanFactory();
		}
		throw new IllegalStateException("Could not locate BeanDefinitionRegistry");
	}
}
 
- 创建 BeanDefinitionLoader 主要是把 BeanDefinitionRegistry 以及主类的 sources 进行赋值初始化
 
 
public class SpringApplication {
	private final Object[] sources;
	private final AnnotatedBeanDefinitionReader annotatedReader;
	private final XmlBeanDefinitionReader xmlReader;
	private BeanDefinitionReader groovyReader;
	private final ClassPathBeanDefinitionScanner scanner;
	private ResourceLoader resourceLoader;
	...
	protected BeanDefinitionLoader createBeanDefinitionLoader(BeanDefinitionRegistry registry, Object[] sources) {
		
		return new BeanDefinitionLoader(registry, sources);
	}
	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 (isGroovyPresent()) {
			this.groovyReader = new GroovyBeanDefinitionReader(registry);
		}
		
		this.scanner = new ClassPathBeanDefinitionScanner(registry);
		
		this.scanner.addExcludeFilter(new ClassExcludeFilter(sources));
	}
}
 
- 创建 BeanDefinitionLoader 成功后,就可以开始执行 load(),这里主要是先把主类注册到 IOC 容器中去
 
 
public class SpringApplication {
	private BeanNameGenerator beanNameGenerator;
	...
	protected void load(ApplicationContext context, Object[] sources) {
		if (logger.isDebugEnabled()) {
			logger.debug("Loading source " + StringUtils.arrayToCommaDelimitedString(sources));
		}
		
		BeanDefinitionLoader loader = createBeanDefinitionLoader(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();
	}
}
 
- 其中 load() 通过 AnnotatedBeanDefinitionReader 将主类 source 注册进 beanDefinitionMap 中
 
 
class BeanDefinitionLoader {
	
	private final AnnotatedBeanDefinitionReader annotatedReader;
	...
	int load() {
		int count = 0;
		for (Object source : this.sources) {
			count += load(source);
		}
		return count;
	}
	
	private int load(Object source) {
		Assert.notNull(source, "Source must not be null");
		
		if (source instanceof Class<?>) {
			return load((Class<?>) source);
		}
		...
	}
	private int load(Class<?> source) {
		
		if (isGroovyPresent() && GroovyBeanDefinitionSource.class.isAssignableFrom(source)) {
			
			GroovyBeanDefinitionSource loader = BeanUtils.instantiateClass(source, GroovyBeanDefinitionSource.class);
			load(loader);
		}
		if (isComponent(source)) { 
			
			this.annotatedReader.register(source);
			return 1;
		}
		return 0;
	}
}
 
- 调用 register() 方法时,真正会传到 doRegisterBean() 进行执行。首先会把主类转换成 AnnotatedGenericBeanDefinition,然后获取主类的名称,把名称和 AnnotatedGenericBeanDefinition 封装成 BeanDefinitionHolder 后,注册到上下文中
 
 
public class AnnotatedBeanDefinitionReader {
	...
	public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}
	public void registerBean(Class<?> beanClass) {
		doRegisterBean(beanClass, null, null, null, null);
	}
	private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {
		
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
		abd.setInstanceSupplier(supplier);
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}
		
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
}
 
- 注册到容器中,简单而言就是调用 BeanDefinitionRegistry 把 BeanDefinitionHolder 的 name 和 AnnotatedGenericBeanDefinition 装配进去
 
 
public abstract class 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);
            }
        }
    }
}
 
- 最后会把 name 和 AnnotatedGenericBeanDefinition 存入到 beanDefinitionMap 中
 
 
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
	...
    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 var8) {
                throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", var8);
            }
        }
        BeanDefinition existingDefinition = (BeanDefinition)this.beanDefinitionMap.get(beanName);
        if (existingDefinition != null) {
            if (!this.isAllowBeanDefinitionOverriding()) {
                throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
            }
            if (existingDefinition.getRole() < beanDefinition.getRole()) {
                if (this.logger.isInfoEnabled()) {
                    this.logger.info("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.isDebugEnabled()) {
                    this.logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
                }
            } else if (this.logger.isTraceEnabled()) {
                this.logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]");
            }
            this.beanDefinitionMap.put(beanName, beanDefinition);
        } else {
            if (this.hasBeanCreationStarted()) {
                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;
                    this.removeManualSingletonName(beanName);
                }
            } else {
                
                this.beanDefinitionMap.put(beanName, beanDefinition);
                this.beanDefinitionNames.add(beanName);
                this.removeManualSingletonName(beanName);
            }
            this.frozenBeanDefinitionNames = null;
        }
        if (existingDefinition == null && !this.containsSingleton(beanName)) {
            if (this.isConfigurationFrozen()) {
                this.clearByTypeCache();
            }
        } else {
            this.resetBeanDefinition(beanName);
        }
    }	
}
 
- 总结
 