从Spring到SpringBoot

一、从Spring到SpringBoot

随着Spring的生态体系越来越壮大,Spring也变得越来越复杂,越来越臃肿。比如你想基于一套SSM的框架进行开发,那么你需要配置很多的东西,整合很多的东西。

因此Spring Boot应运而生。那么他基于什么变得简单呢?

就是:约定大于配置

什么是SpringBoot?

SpringBoot使创建独立运行、生产级别的Spring应用变得容易,你可以直接运行它。大部分SpringBoot应用仅仅需要少量的配置就可以使用。

SpringBoot的特性:

  • 创建独立运行的Spring应用
  • 直接嵌入Tomcat或Jetty,Undertow,无需部署WAR包
  • 提供starter依赖简化配置
  • 在必要时自动化配置Spring和其他第三方依赖库
  • 提供生产production-ready特性,例如健康检查,外部配置等
  • 完全零代码生产和不需要XML配置

快速构建Maven项目

可以在https://start.spring.io进行快速生成一个SpringBoot的项目。

从Spring到SpringBoot

二、SpringBoot 核心原理

自动化配置、基于Configuration,EnableXX,Condition

spring-boot-starter:脚手架核心,快速整合第三方类库

从Spring到SpringBoot

AutoConfigurationImportSelector类的getAutoConfigurationEntry方法会先判断自动配置是否开启,如果开启,会去扫描所有配置在spring.factories里的name为EnableAutoConfiguration的类。

主要代码如下:

 protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.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() {
        //去扫描name为EnableAutoConfiguration的类
        return EnableAutoConfiguration.class;
    }
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
		ClassLoader classLoaderToUse = classLoader;
		if (classLoaderToUse == null) {
			classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
		}
		String factoryTypeName = factoryType.getName();
		//根据factoryTypeName去load类
		return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
	}

	private static Map<String, List<String>> loadSpringFactories(ClassLoader classLoader) {
		Map<String, List<String>> result = cache.get(classLoader);
		if (result != null) {
			return result;
		}

		result = new HashMap<>();
		try {
		    //FACTORIES_RESOURCE_LOCATION静态常量,值为META-INF/spring.factories,读取spring.factories文件,并进行处理
			Enumeration<URL> urls = classLoader.getResources(FACTORIES_RESOURCE_LOCATION);
			...

条件化自动配置的注解

  • @ConditionalOnBean
  • @ConditionalOnClass
  • @ConditionalOnJava
  • @ConditionalOnMissingBean
  • @ConditionalOnMissingClass
  • @ConditionalOnProperty
  • @ConditionalOnResource
  • @ConditionalOnWebApplication

自定义starter

可以参看我的这篇博客:
https://www.cnblogs.com/javammc/p/13893698.html

为什么要约定大于配置

优势在于,开箱即用:

  1. Maven的目录结构:默认有resources文件夹存放配置文件。默认打包方式为jar
  2. 默认的配置文件:application.properties或application.yml
  3. 默认通过spring.profiles.active属性来决定运行环境时的配置文件
  4. EnableAutoConfiguration默认对于依赖的starter自动装配
  5. spring-boot-start-web中默认包含spring-mvc相关依赖以及内置的web容器,使得构建一个web应用更加简单。
上一篇:Java 类加载器


下一篇:ClassLoader读取文件,springboot打jar包后读取不到