接着上一篇SpringBoot基础(一、快速入门)的介绍,我们来简单的谈谈SpringBoot的原理分析。
谈到原理,那么就从它的核心入手,“约定大于配置”,这句话可以分为以下两点。
根据第一篇文章的项目,我们好像没什么也选项呀!我们就配置了坐标和引导类。
先从坐标入手吧!
先CTRL+左键,进入 spring-boot-starter-parent 这个父工程看看。
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent> //引入父工程
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
<artifactId>spring-boot-starter-parent</artifactId>
<packaging>pom</packaging>
<name>Spring Boot Starter Parent</name>
<description>Parent pom providing dependency and plugin management for applications
built with Maven</description>
<url>https://projects.spring.io/spring-boot/#/spring-boot-starter-parent</url>
<properties> //属性配置
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<resource.delimiter>@</resource.delimiter>
<maven.compiler.source>${java.version}</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>${java.version}</maven.compiler.target>
</properties>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>${basedir}/src/main/resources</directory>
<includes> //导入非默认配置资源
<include>**/application*.yml</include> //.yml文件类型 server: {port: 8888,xxx: xxx},{...}
<include>**/application*.yaml</include>
<include>**/application*.properties</include>
</includes>
</resource>
<pluginManagement> //插件管理
....
</pluginManagement>
</build>
</project>
这个工程有一些属性配置,导入非默认配置,插件管理
好像 spring-boot-starter-parent , 还存在父工程 spring-boot-dependencies。同理,进去看看
<?xml version="1.0" encoding="utf-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.5.RELEASE</version>
<packaging>pom</packaging>
<name>Spring Boot Dependencies</name>
<description>Spring Boot Dependencies</description>
<url>https://projects.spring.io/spring-boot/#</url>
<licenses>
....
</licenses>
<developers>
....
</developers>
<scm>
<url>https://github.com/spring-projects/spring-boot</url>
</scm>
<properties>
<spring.version>5.1.7.RELEASE</spring.version> //版本锁定
<junit.version>4.12</junit.version>
....
</properties>
<dependencyManagement>
<dependencies>
<dependency> //导入坐标
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
</dependencies>
....
</dependencyManagement>
<build>
<pluginManagement>
.... //导入插件
</pluginManagement>
</build>
</project>
嗯,很多从开始的版本锁定,依赖管理,插件管理。也就是启动Spring所需要的配置都有默认的了??
那么我么加的WEB功能呢? 也有类似的坐标??
那么进去看看 spring-boot-starter-web。
我们可以猜猜看,这个坐标下有什么东西 springMVC的坐标? Spring-web坐标??json工具的坐标??
点击进去,发现,答对了,这个都存在,还有其他的tomcat服务器坐标等。。。
但是,发现还引用spring-boot-starters这个父工程,相比第一个差了一个parent。里面有的咱就不说了,跟第一个类似,有兴趣可以试试。
现在从引导类入手,看看有啥,没啥, 就一个注解好像特殊点。那就看看注解
按住CTRL+左键进入 @SpringBootApplication 注解
package org.springframework.boot.autoconfigure;
import ...
@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 {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
......
}
发现三个有点眼熟的注解,并分别点进去看看
@SpringBootConfiguration,里面有一个@Configuration注解,这不就是基于Java的配置吗?标志着该类是一个配置类。
@ComponentScan,相当开启全局注解扫描。
@EnableAutoConfiguration,SpringBoot自动配置功能开启
@EnableAutoConfiguration --> @Import({AutoConfigurationImportSelector.class}) -->AutoConfigurationImportSelector.class
public class AutoConfigurationImportSelector {
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;
}
....
}
我们根据提示,知道AutoConfigurationImportSelector此类,会加载META-INF/目录下的文件。那找找这个类看看呗。
也就是此类中存有SpringBoot自动配置的信息。
一、我们可以得到默认配置信息名称和值,以及配置方式。
二、spring-boot-starter-parent中提到加载非默认配置信息,进而让可以改变SpringBoot的配置信息。
那我们修改8080端口看看吧,改为8888。
寻找到端口的配置信息
ServletWebServerFactoryAutoConfiguration --> @EnableConfigurationProperties({ServerProperties.class}) --> ServerProperties
@ConfigurationProperties( //配置信息映射注解,作用同@Value("${server.port},{server.xxx}")
prefix = "server",
ignoreUnknownFields = true
)
public class ServerProperties {
private Integer port;
....
}
{
"name": "server.port",
"type": "java.lang.Integer",
"description": "Server HTTP port.",
"sourceType": "org.springframework.boot.autoconfigure.web.ServerProperties",
"defaultValue": 8080
},
既然知道了是怎么样是属性了,那我们配8888端口看看呗!
创建application.properties文件,并写上server.port=8888
访问看看
SpringBoot简单的原理分析,到此就结束了。约定大于配置,一系列的默认自动配置,降低人为因数导致的错误,简化开发。
也就两点,起步依赖 、自动配置 。