SpringBoot-源码剖析

这是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);
}
相关推荐
ch.ju1 小时前
Java程序设计(第3版)第二章——Java中的数据类型
java
MwEUwQ3Gx1 小时前
深入理解 Java Deque 的设计哲学
java·开发语言·python
麦芽糖02191 小时前
若依整合AI一 基础应用篇
java
进朱者赤1 小时前
从 Java / Go 后端视角系统理解 TypeScript 与 Node.js:从看不懂到能参与 openclaw 这类项目开发
java·golang·typescript
MX_93591 小时前
SpringMVC静态资源访问、annotation-driven的使用原理及数据响应模式
java·后端·spring
人间寥寥情难诉1 小时前
LRU算法本地实现
java·算法·spring
djBe17esS1 小时前
实战:Java 日志中打印服务器 IP,快速区分多服务器日志归属
java·服务器·tcp/ip
woai33642 小时前
JVM学习-基础篇-垃圾回收
java·jvm·学习
七夜zippoe2 小时前
应用安全实践(一):常见Web漏洞(OWASP Top 10)与防护
java·前端·网络·安全·owasp