
这是SpringBoot的启动类
java
@SpringBootApplication
public class Demo01Application {
public static void main(String[] args) {
SpringApplication.run(Demo01Application.class, args);
}
}
@SpringBootApplication注解解析
java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
/*
* 自动装配要排除的类,功能来自于 @EnableAutoConfiguration
* */
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
/*
* 自动装配要排除的类名,功能来自于 EnableAutoConfiguration
* */
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
/**
* 配置扫描的包,功能来自于 @ComponentScan
* */
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
/**
* 配置扫描的class,该class所在的包都会被扫描,功能来自于 @ComponentScan
* */
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
/**
* 是否启动 @Bean 方法代理,功能来自于 @Configuration
* */
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
这几个注解是Spring中的元注解,这个注解意义不大
@SpringBootConfiguration这个就要涉及到一些内容了
java
@Configuration
public @interface SpringBootConfiguration {
//断言
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
@SpringBootConfiguration
标注这个类是一个配置类;
它只是@Configuration注解的派生注解;
它与@Configuration注解的功能一致;
只不过@SpringBootConfiguration是springboot的注解,而@Configuration是spring的注解。
@Configuration 可以理解为一个Configuration就是对应的一个Spring的xml版的容器;(beans)
@Component
@Bean
是两种使用注解来定义bean的方式。
@Component(和@Service和@Repository)用于自动检测和使用类路径扫描自动配置bean。注释类和bean之间存在隐式的一对一映射(即每个类一个bean)。
@Bean用于显式声明单个bean,而不是让Spring像上面那样自动执行它。它将bean的声明与类定义分离,并允许您精确地创建和配置bean。
@Bean则常和@Configuration注解搭配使用:
java@Configuration public class WebSocketConfig { @Bean public Student student(){ return new Student(); } }都可以使用@Autowired或者@Resource注解注入;
@Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。
两者的区别:
如果想将第三方的类变成组件,你又没有没有源代码,也就没办法使用@Component进行自动配置,这种时候使用@Bean就比较合适了。
另外@Bean注解的方法返回值是对象,可以在方法中为对象设置属性。
@EnableAutoConfiguration
java
@Target(ElementType.TYPE) // 注解应用目标为类
@Retention(RetentionPolicy.RUNTIME) // 注解保留到运行时
@Documented // 注解包含在 javadoc 中
@Inherited // 子类可以继承该注解
@AutoConfigurationPackage // 标记自动配置的包,用于扫描起始包
@Import(AutoConfigurationImportSelector.class) // 导入自动配置导入选择器类
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration"; // 环境属性,用于手动开启或关闭自动配置
Class<?>[] exclude() default {}; // 排除特定的自动配置类,使其不会被应用
String[] excludeName() default {}; // 排除特定名称的自动配置类,使其不会被应用
}
现在来分析 @EnableAutoConfiguration中的**@AutoConfigurationPackage**注解的作用
@AutoConfigurationPackage
java
@Target(ElementType.TYPE) // 注解应用目标为类
@Retention(RetentionPolicy.RUNTIME) // 注解保留到运行时
@Documented // 注解包含在 javadoc 中
@Inherited // 子类可以继承该注解
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}
AutoConfigurationPackages.Registrar.class
java
public abstract class AutoConfigurationPackages {
private static final Log logger = LogFactory.getLog(AutoConfigurationPackages.class);
private static final String BEAN = AutoConfigurationPackages.class.getName();
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//将注解标注的元信息传入,获取相应的包名
register(registry, new PackageImport(metadata).getPackageName());
}
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImport(metadata));
}
}
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
//这里参数 packageNames 缺省情况下就是一个字符串,是使用了注解
//@SpringBootApplication 的 Spring Boot 应用程序入口所在的包
if (registry.containsBeanDefinition(BEAN)) {
//如果该bean已经注册,则将要注册包名称添加进去
BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
// bean 是 BasePackages,构造方法是 BasePackages(String... names),这里获取原本的构造参数的值
ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
// 将原本的构造参数值,以及传入的 packageNames 统一添加到构造方法的第0个参数值上
constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
}
else {
//如果该Bean尚未注册,则注册该Bean,参数中提供的包名称会被设置到Bean定义中去
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(BasePackages.class);
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN, beanDefinition);
}
}
}
接着来分析**@EnableAutoConfiguration中的@Import(AutoConfigurationImportSelector.class)**注解的作用
javascript
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
.loadMetadata(this.beanClassLoader);
// 加载自动配置类
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
// 又一次判断是否开启自动装配
// 获取是否有配置spring.boot.enableautoconfiguration 属性,默认返回true
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
// 获取注解的属性
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 加载候选的自动配置类
// 【1】得到spring.factories 文件配置的所有的自动配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 去重,转换成set,再转换成list
//利用LinkedHashSet 移除重复的配置类
configurations = removeDuplicates(configurations);
//得到要排除的自动配置类,比如注解属性 exclude 的配置类
//比如:@SpringBootApplication(exclude = FreeMarkAutoConfiguration.class)
//将会获得到exclude = FreeMarkAutoConfiguration.class的注解数据
// 获取的排除的类,其实就是处理@EnableAutoConfiguration的exclude与excludeName
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
// 检查排除的类是否合法,再移除需要排除的配置类
// 检查要被排除的配置类,
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// 过滤一些不需要自动装配的类,不过这个方法并没有过滤成功
configurations = filter(configurations, autoConfigurationMetadata);
// 触发 AutoConfigurationImportEvent 事件
fireAutoConfigurationImportEvents(configurations, exclusions);
// 最终返回的值
return new AutoConfigurationEntry(configurations, exclusions);
}
@Override
public Class<? extends Group> getImportGroup() {
return AutoConfigurationGroup.class;
}
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass() == AutoConfigurationImportSelector.class) {
return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
}
return true;
}
protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
String name = getAnnotationClass().getName();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
+ " annotated with " + ClassUtils.getShortName(name) + "?");
return attributes;
}
/**
* Return the source annotation class used by the selector.
* @return the annotation class
*/
protected Class<?> getAnnotationClass() {
return EnableAutoConfiguration.class;
}
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
// SPI机制加载自动配置类,getSpringFactoriesLoaderFactoryClass() 返回的是
// EnableAutoConfiguration
//这个方法需要传入两个参数 getSpringFactoriesLoaderFactoryClass()和 getBeanClassLoader()
//getSpringFactoriesLoaderFactoryClass() 这个方法返沪的是 enableAutoConfiguration.class
// getBeanClassLoader() 这个方法返回的是 beanClassLoader(类加载器)
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
+ "are using a custom packaging, make sure that file is correct.");
return configurations;
}
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
List<String> invalidExcludes = new ArrayList<>(exclusions.size());
for (String exclusion : exclusions) {
// ClassLoader 中加载了exclusion类,但自动配置的类中不包括该类,就会加入到 invalidExcludes 集合中
if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) && !configurations.contains(exclusion)) {
invalidExcludes.add(exclusion);
}
}
if (!invalidExcludes.isEmpty()) {
// 这里会抛出异常
handleInvalidExcludes(invalidExcludes);
}
}
protected void handleInvalidExcludes(List<String> invalidExcludes) {
StringBuilder message = new StringBuilder();
for (String exclude : invalidExcludes) {
message.append("\t- ").append(exclude).append(String.format("%n"));
}
throw new IllegalStateException(String.format(
"The following classes could not be excluded because they are not auto-configuration classes:%n%s",
message));
}
protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
Set<String> excluded = new LinkedHashSet<>();
excluded.addAll(asList(attributes, "exclude"));
excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
excluded.addAll(getExcludeAutoConfigurationsProperty());
return excluded;
}
private List<String> getExcludeAutoConfigurationsProperty() {
if (getEnvironment() instanceof ConfigurableEnvironment) {
Binder binder = Binder.get(getEnvironment());
return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList)
.orElse(Collections.emptyList());
}
String[] excludes = getEnvironment().getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class);
return (excludes != null) ? Arrays.asList(excludes) : Collections.emptyList();
}
private List<String> filter(List<String> configurations, AutoConfigurationMetadata autoConfigurationMetadata) {
long startTime = System.nanoTime();
String[] candidates = StringUtils.toStringArray(configurations);
boolean[] skip = new boolean[candidates.length];
boolean skipped = false;
// getAutoConfigurationImportFilters():加载配置文件中的 AutoConfigurationImportFilter
for (AutoConfigurationImportFilter filter : getAutoConfigurationImportFilters()) {
invokeAwareMethods(filter);
boolean[] match = filter.match(candidates, autoConfigurationMetadata);
for (int i = 0; i < match.length; i++) {
if (!match[i]) {
skip[i] = true;
candidates[i] = null;
skipped = true;
}
}
}
if (!skipped) {
return configurations;
}
List<String> result = new ArrayList<>(candidates.length);
for (int i = 0; i < candidates.length; i++) {
if (!skip[i]) {
result.add(candidates[i]);
}
}
if (logger.isTraceEnabled()) {
int numberFiltered = configurations.size() - result.size();
logger.trace("Filtered " + numberFiltered + " auto configuration class in "
+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
}
return new ArrayList<>(result);
}
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
}
protected final <T> List<T> removeDuplicates(List<T> list) {
return new ArrayList<>(new LinkedHashSet<>(list));
}
protected final List<String> asList(AnnotationAttributes attributes, String name) {
String[] value = attributes.getStringArray(name);
return Arrays.asList(value);
}
private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
List<AutoConfigurationImportListener> listeners = getAutoConfigurationImportListeners();
if (!listeners.isEmpty()) {
AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
for (AutoConfigurationImportListener listener : listeners) {
invokeAwareMethods(listener);
listener.onAutoConfigurationImportEvent(event);
}
}
}
protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() {
return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader);
}
private void invokeAwareMethods(Object instance) {
if (instance instanceof Aware) {
if (instance instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) instance).setBeanClassLoader(this.beanClassLoader);
}
if (instance instanceof BeanFactoryAware) {
((BeanFactoryAware) instance).setBeanFactory(this.beanFactory);
}
if (instance instanceof EnvironmentAware) {
((EnvironmentAware) instance).setEnvironment(this.environment);
}
if (instance instanceof ResourceLoaderAware) {
((ResourceLoaderAware) instance).setResourceLoader(this.resourceLoader);
}
}
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory);
this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
}
protected final ConfigurableListableBeanFactory getBeanFactory() {
return this.beanFactory;
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
protected ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
protected final Environment getEnvironment() {
return this.environment;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
protected final ResourceLoader getResourceLoader() {
return this.resourceLoader;
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 1;
}
private static class AutoConfigurationGroup
implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
private final Map<String, AnnotationMetadata> entries = new LinkedHashMap<>();
private final List<AutoConfigurationEntry> autoConfigurationEntries = new ArrayList<>();
private ClassLoader beanClassLoader;
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
private AutoConfigurationMetadata autoConfigurationMetadata;
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.beanClassLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
//这里是处理自动配置类,比如过滤掉不符合匹配条件的自动配置类
@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are supported, got %s",
AutoConfigurationImportSelector.class.getSimpleName(),
deferredImportSelector.getClass().getName()));
// 【1】调用外部类的 getAutoConfigurationEntry(...) 方法 得到自动配置类放入 autoConfigurationEntry 对象中
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(getAutoConfigurationMetadata(), annotationMetadata);
// 【2】又将封装了自动装配类的autoConfigurationEntry对象装进autoConfigurationEntries集合
this.autoConfigurationEntries.add(autoConfigurationEntry);
// 【3】遍历刚获取的自动配置类
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
// 这里符合条件的自动配置类作为key,annotationMetadata 作为值放进 entries 集合
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
@Override
public Iterable<Entry> selectImports() {
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
}
// 处理过滤
Set<String> allExclusions = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
// 类型转换
Set<String> processedConfigurations = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
// 去除需要过滤的类
processedConfigurations.removeAll(allExclusions);
// 进行排序
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
}
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
// 在这里传入的 autoConfigurationMetadata
if (this.autoConfigurationMetadata == null) {
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
}
return this.autoConfigurationMetadata;
}
private List<String> sortAutoConfigurations(Set<String> configurations,
AutoConfigurationMetadata autoConfigurationMetadata) {
// 先创建了 AutoConfigurationSorter 对象,
// 然后调用 AutoConfigurationSorter.getInPriorityOrder 进行排序
return new AutoConfigurationSorter(getMetadataReaderFactory(), autoConfigurationMetadata)
.getInPriorityOrder(configurations);
}
private MetadataReaderFactory getMetadataReaderFactory() {
try {
return this.beanFactory.getBean(SharedMetadataReaderFactoryContextInitializer.BEAN_NAME,
MetadataReaderFactory.class);
}
catch (NoSuchBeanDefinitionException ex) {
return new CachingMetadataReaderFactory(this.resourceLoader);
}
}
}
protected static class AutoConfigurationEntry {
private final List<String> configurations;
private final Set<String> exclusions;
private AutoConfigurationEntry() {
this.configurations = Collections.emptyList();
this.exclusions = Collections.emptySet();
}
AutoConfigurationEntry(Collection<String> configurations, Collection<String> exclusions) {
this.configurations = new ArrayList<>(configurations);
this.exclusions = new HashSet<>(exclusions);
}
public List<String> getConfigurations() {
return this.configurations;
}
public Set<String> getExclusions() {
return this.exclusions;
}
}
}
SpringApplication解析
java
@SpringBootApplication
public class Demo01Application {
public static void main(String[] args) {
SpringApplication.run(Demo01Application.class, args);
}
}
现在来看SpringApplication中对应的方法具体做了什么?
java
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) {
return new SpringApplication(primarySources).run(args);
}
很明显现在在调用完run之后,返回了一个SpringApplication对应的对象,并将传入的class传入之后调用了run方法,真正进行执行的方法就在这个run里面。
解剖对应的run方法
java
public ConfigurableApplicationContext run(String... args) {
StopWatch stopWatch = new StopWatch();
stopWatch.start();
ConfigurableApplicationContext context = null;
Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList<>();
// 配置一个系统属性:java.awt.headless
// java.awt.headless模式是系统的一种配置模式。在系统可能缺少显示设备、键盘或鼠标这些外设的情况下可以使用该模式
configureHeadlessProperty();
// 获取监听器,也是从 META-INF/spring.factories 中获取
SpringApplicationRunListeners listeners = getRunListeners(args);
// starting():首次启动run方法时立即调用。可用于非常早期的初始化(准备运行时环境之前)。
listeners.starting();
try {
// 封装传入的参数
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 处理环境参数
ConfigurableEnvironment environment = prepareEnvironment(listeners, applicationArguments);
// 如果有配置 spring.beaninfo.ignore,则将该配置设置进系统参数
configureIgnoreBeanInfo(environment);
// 输出banner
Banner printedBanner = printBanner(environment);
// 创建applicationContext
context = createApplicationContext();
// 启动错误报告的自定义回调接口,直接进行反射的原理进行处理问题
exceptionReporters = getSpringFactoriesInstances(SpringBootExceptionReporter.class,
new Class[] { ConfigurableApplicationContext.class }, context);
// 准备上下文,设置了一系列的属性值
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
// 调用 AbstractApplicationContext.refresh,启动spring容器
refreshContext(context);
afterRefresh(context, applicationArguments);
stopWatch.stop();
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), stopWatch);
}
// 发布事件
listeners.started(context);
// 调用 runner,实现了 ApplicationRunner或CommandLineRunner 的接口
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, listeners);
throw new IllegalStateException(ex);
}
try {
listeners.running(context);
}
catch (Throwable ex) {
handleRunFailure(context, ex, exceptionReporters, null);
throw new IllegalStateException(ex);
}
return context;
}
configureHeadlessProperty
配置一个系统属性:java.awt.headless
java.awt.headless 模式是系统的一种配置模式,在系统可能缺少显示设备、键盘或者鼠标这些外设的情况下可以使用该模式
java
private void configureHeadlessProperty() {
System.setProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS,
System.getProperty(SYSTEM_PROPERTY_JAVA_AWT_HEADLESS, Boolean.toString(this.headless)));
}
getRunListeners
获取监听器,也是从 META-INF/spring.factories 中获取
java
private SpringApplicationRunListeners getRunListeners(String[] args) {
Class<?>[] types = new Class<?>[] { SpringApplication.class, String[].class };
return new SpringApplicationRunListeners(logger,
getSpringFactoriesInstances(SpringApplicationRunListener.class, types, this, args));
}
SpringApplicationRunListeners
java
SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners) {
this.log = log;
this.listeners = new ArrayList<>(listeners);
}
getSpringFactoriesInstances
java
private <T> Collection<T> getSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes, Object... args) {
ClassLoader classLoader = getClassLoader();
// SpringFactoriesLoader.loadFactoryNames(...) : 从META-INF/spring.factories加载内容
Set<String> names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader));
// 实例化,使用的反射操作
List<T> instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names);
// 排序,比较的是 @Order 注解,或实现的 Orderd 接口
AnnotationAwareOrderComparator.sort(instances);
return instances;
}
createSpringFactoriesInstances
实例化,使用的反射操作
java
private <T> List<T> createSpringFactoriesInstances(Class<T> type, Class<?>[] parameterTypes,
ClassLoader classLoader, Object[] args, Set<String> names) {
List<T> instances = new ArrayList<>(names.size());
for (String name : names) {
try {
Class<?> instanceClass = ClassUtils.forName(name, classLoader);
//断言
Assert.isAssignable(type, instanceClass);
Constructor<?> constructor = instanceClass.getDeclaredConstructor(parameterTypes);
// 使用反射实例化
T instance = (T) BeanUtils.instantiateClass(constructor, args);
instances.add(instance);
}
catch (Throwable ex) {
throw new IllegalArgumentException("Cannot instantiate " + type + " : " + name, ex);
}
}
return instances;
}
prepareEnvironment
处理环境变量
java
private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
ApplicationArguments applicationArguments) {
// Create and configure the environment
// 获取环境,如果不存在则创建
ConfigurableEnvironment environment = getOrCreateEnvironment();
// 配置运行时环境
configureEnvironment(environment, applicationArguments.getSourceArgs());
ConfigurationPropertySources.attach(environment);
// 【回调】SpringApplicationRunListener 的 environmentPrepared 方法
// (Environment构建完成,但在创建ApplicationContext之前)
listeners.environmentPrepared(environment);
// 环境与应用绑定
bindToSpringApplication(environment);
if (!this.isCustomEnvironment) {
environment = new EnvironmentConverter(getClassLoader()).convertEnvironmentIfNecessary(environment,
deduceEnvironmentClass());
}
ConfigurationPropertySources.attach(environment);
return environment;
}
configureEnvironment
配置运行时环境
java
protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
if (this.addConversionService) {
// 添加转换器,处理参数类型转换,如 String转Number,Integer转Enum等
ConversionService conversionService = ApplicationConversionService.getSharedInstance();
environment.setConversionService((ConfigurableConversionService) conversionService);
}
// 将启动参数添加到 environment 中
configurePropertySources(environment, args);
// 处理 ActiveProfiles 值
configureProfiles(environment, args);
}
configurePropertySources
将启动参数添加到环境中
java
protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
MutablePropertySources sources = environment.getPropertySources();
// 设置默认属性
if (this.defaultProperties != null && !this.defaultProperties.isEmpty()) {
sources.addLast(new MapPropertySource("defaultProperties", this.defaultProperties));
}
if (this.addCommandLineProperties && args.length > 0) {
String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
if (sources.contains(name)) {
PropertySource<?> source = sources.get(name);
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(
// 处理启动时传入的参数
new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
composite.addPropertySource(source);
sources.replace(name, composite);
}
else {
sources.addFirst(new SimpleCommandLinePropertySource(args));
}
}
}
configureProfiles
处理对应的数据信息,保存到环境中
java
protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
Set<String> profiles = new LinkedHashSet<>(this.additionalProfiles);
profiles.addAll(Arrays.asList(environment.getActiveProfiles()));
environment.setActiveProfiles(StringUtils.toStringArray(profiles));
}
configureIgnoreBeanInfo
如果有配置 spring.beaninfo.ignore,则将该配置设置进系统参数
java
private void configureIgnoreBeanInfo(ConfigurableEnvironment environment) {
if (System.getProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME) == null) {
Boolean ignore = environment.getProperty("spring.beaninfo.ignore", Boolean.class, Boolean.TRUE);
System.setProperty(CachedIntrospectionResults.IGNORE_BEANINFO_PROPERTY_NAME, ignore.toString());
}
}
createApplicationContext
创建ApplicationContext,理解Spring中如何启动容器就能理解这一块的东西
java
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext";
protected ConfigurableApplicationContext createApplicationContext() {
Class<?> contextClass = this.applicationContextClass;
if (contextClass == null) {
try {
switch (this.webApplicationType) {
case SERVLET:
// 使用的是 AnnotationConfigServletWebServerApplicationContext
contextClass = Class.forName(DEFAULT_SERVLET_WEB_CONTEXT_CLASS);
break;
case REACTIVE:
contextClass = Class.forName(DEFAULT_REACTIVE_WEB_CONTEXT_CLASS);
break;
default:
// 默认使用的是 AnnotationConfigApplicationContext
contextClass = Class.forName(DEFAULT_CONTEXT_CLASS);
}
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Unable create a default ApplicationContext, please specify an ApplicationContextClass", ex);
}
}
return (ConfigurableApplicationContext) BeanUtils.instantiateClass(contextClass);
}
prepareContext
准备上下文,设置了一系列的属性值
java
private void prepareContext(ConfigurableApplicationContext context, ConfigurableEnvironment environment,
SpringApplicationRunListeners listeners, ApplicationArguments applicationArguments, Banner printedBanner) {
// 将创建好的应用环境设置到IOC容器中
context.setEnvironment(environment);
postProcessApplicationContext(context);
// 应用Initializer进行初始化操作
applyInitializers(context);
// 监听器:SpringApplicationRunListeners的contextPrepared方法
// (在创建和准备ApplicationContext之后,但在加载之前)
listeners.contextPrepared(context);
if (this.logStartupInfo) {
logStartupInfo(context.getParent() == null);
logStartupProfileInfo(context);
}
// Add boot specific singleton beans
// 获取beanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
beanFactory.registerSingleton("springApplicationArguments", applicationArguments);
if (printedBanner != null) {
beanFactory.registerSingleton("springBootBanner", printedBanner);
}
if (beanFactory instanceof DefaultListableBeanFactory) {
// 是否允许bean的信息被覆盖
((DefaultListableBeanFactory) beanFactory)
.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 处理懒加载
if (this.lazyInitialization) {
context.addBeanFactoryPostProcessor(new LazyInitializationBeanFactoryPostProcessor());
}
// Load the sources
// 获取所有资源
Set<Object> sources = getAllSources();
Assert.notEmpty(sources, "Sources must not be empty");
// 加载 class
load(context, sources.toArray(new Object[0]));
// 发布事件
listeners.contextLoaded(context);
}