SpringBoot
SpringBoot
- SpringBoot基于约定优于配置的思想,可以让开发人员不必在配置与逻辑业务之间进行思维的切换
- 全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率
SpringBoot的特点
- 为基于Spring的开发提供更快的入门体验
- 开箱即用,没有代码生成,也无需XML配置。同时也可以修改默认值来满足特定的需求
- 提供了一些大型项目中常见的非功能性特性,如嵌入式服务器、安全、指标,健康检测、外部配置等
- SpringBoot不是对Spring功能上的增强,而是提供了一种快速使用Spring的方式
SpringBoot的核心功能
- 起步依赖
- 起步依赖本质上是一个Maven项目对象模型(POM),定义了对其他库的传递依赖,这些东西加在一起即支持某项功能
- 简单的说,起步依赖就是将具备某种功能的坐标打包到一起,并提供一些默认的功能
- 自动配置
- Spring Boot的自动配置是一个运行时的过程,考虑了众多因素,才决定Spring配置应该用哪个,不该用哪个
- 该过程是Spring自动完成的
SpringBoot快速入门
- 创建maven工程(jar)
- 添加SpringBoot的起步依赖
- SpringBoot要求,项目要继承SpringBoot的起步依赖spring-boot-starter-parent
- SpringBoot要集成SpringMVC进行Controller的开发,所以项目要导入web的启动依赖
[XML] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
|
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version></parent><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency></dependencies> |
编写SpringBoot引导类
- 要通过SpringBoot提供的引导类起步SpringBoot才可以进行访问
[Java] 纯文本查看 复制代码
|
1
2
3
4
5
6
7
8
9
|
import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class MySpringBootApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class); }} |
- 编写Controller
[Java] 纯文本查看 复制代码
|
1
2
3
4
5
6
7
|
@RestControllerpublic class QuickStartController { @RequestMapping("/quick") public String quick() { return "springboot 访问成功!"; }} |
- 访问
- http://localhost:8080/quick
快速入门解析
- SpringBoot代码解析
- @SpringBootApplication
- 标注SpringBoot的启动类
- SpringApplication.run(MySpringBootApplication.class) 代表运行SpringBoot的启动类
- SpringBoot启动类的字节码对象
- @SpringBootApplication
- SpringBoot工程热部署
- 我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样很浪费时间
- 我们可以在修改代码后不重启就能生效
- 在 pom.xml 中添加如下配置就可以实现这样的功能,我们称之为热部署
- 注意:IDEA进行SpringBoot热部署失败原因
- 出现这种情况,并不是热部署配置问题
- 其根本原因是因为Intellij IEDA默认情况下不会自动编译
- settint-->compiler-->build project automatically
- 然后按快捷键: Shift+Ctrl+Alt+/,选择Registry
- 选中register
- 勾选compiler.automake.allow.when.app.running
[XML] 纯文本查看 复制代码
|
1
2
3
4
5
|
<!--热部署配置--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId></dependency> |
[Java] 纯文本查看 复制代码
|
1
|
settint-->compiler-->build project automatically |
SpringBoot原理分析分析spring-boot-starter-parent
- 按住Ctrl点击pom.xml中的spring-boot-starter-parent,跳转到了spring-boot-starter-parent的pom.xml,xml配置如下
[XML] 纯文本查看 复制代码
|
1
2
3
4
5
6
|
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.0.1.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath></parent> |
- 按住Ctrl点击pom.xml中的spring-boot-starter-dependencies,跳转到了 spring-boot-starter-dependencies的pom.xml,xml配置如下
[XML] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<properties> <activemq.version>5.15.3</activemq.version> <antlr2.version>2.7.7</antlr2.version> <appengine-sdk.version>1.9.63</appengine-sdk.version> <artemis.version>2.4.0</artemis.version> <aspectj.version>1.8.13</aspectj.version> <assertj.version>3.9.1</assertj.version> <atomikos.version>4.0.6</atomikos.version> <bitronix.version>2.1.4</bitronix.version> <build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version> ……</properties><dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot</artifactId> <version>2.0.1.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-test</artifactId> <version>2.0.1.RELEASE</version> </dependency> ……</dependencies></dependencyManagement><build> <pluginManagement> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <version>${kotlin.version}</version> </plugin> <plugin> <groupId>org.jooq</groupId> <artifactId>jooq-codegen-maven</artifactId> <version>${jooq.version}</version> </plugin> ……… </plugins> </pluginManagement></build> |
- 从上面的spring-boot-starter-dependencies的pom.xml中我们可以发现,一部分坐标的版本、依赖管理、插件管理已经定义好,所以我们的SpringBoot工程继承spring-boot-starter-parent后已经具备版本锁定等配置了
spring-boot-starter-web
- 按住Ctrl点击pom.xml中的spring-boot-starter-web,跳转到了spring-boot-starter-web的pom.xml,xml配置如下
[XML] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
<?xml version="1.0" encoding="UTF-8"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starters</artifactId> <version>2.0.1.RELEASE</version> </parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.0.1.RELEASE</version> <name>Spring Boot Web Starter</name><dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> <version>2.0.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-json</artifactId> <version>2.0.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <version>2.0.1.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.9.Final</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.0.5.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.0.5.RELEASE</version> <scope>compile</scope> </dependency> </dependencies></project> |
- 从上面的spring-boot-starter-web的pom.xml中我们可以发现,spring-boot-starter-web就是将web开发要使用的spring-web、spring-webmvc等坐标进行了“打包”
- 这样我们的工程只要引入spring-boot-starter-web起步依赖的坐标就可以进行web开发了,同样体现了依赖传递的作用
自动配置原理解析
- 按住Ctrl点击查看启动类MySpringBootApplication上的注解@SpringBootApplication
[AppleScript] 纯文本查看 复制代码
|
1
2
3
4
5
6
|
@SpringBootApplicationpublic class MySpringBootApplication { public static void main(String[] args) { SpringApplication.run(MySpringBootApplication.class); }} |
- 注解@SpringBootApplication的源码
[Java] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
|
@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 { /** * Exclude specific auto-configuration classes such that they will never be applied. * @return the classes to exclude */ @AliasFor(annotation = EnableAutoConfiguration.class) Class<?>[] exclude() default {}; ……} |
- @SpringBootConfiguration:等同与@Configuration,既标注该类是Spring的一个配置类
- @EnableAutoConfiguration:SpringBoot自动配置功能开启
- 按住Ctrl点击查看注解@EnableAutoConfiguration
[Java] 纯文本查看 复制代码
|
1
2
3
4
5
6
7
8
9
|
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(AutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration { ………} |
- 其中,@Import(AutoConfigurationImportSelector.class) 导入了AutoConfigurationImportSelector类
- 按住Ctrl点击查看AutoConfigurationImportSelector源码
[Java] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
@Overridepublic String[] selectImports(AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AnnotationAttributes attributes = getAttributes(annotationMetadata); "List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);" configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions); configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return StringUtils.toStringArray(configurations);}protected List<String> "getCandidateConfigurations"(AnnotationMetadata metadata, AnnotationAttributes attributes) { 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;} |
- 其中,SpringFactoriesLoader.loadFactoryNames方法的作用就是从META-INF/spring.factories文件中读取指定类对应的类名称列表
- spring.factories 文件中有关自动配置的配置信息如下
[Java] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
12
13
|
……org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\…… |
- 上面配置文件存在大量的以Configuration为结尾的类名称,这些类就是存有自动配置信息的类,而 SpringApplication在获取这些类名后再加载
- 我们以ServletWebServerFactoryAutoConfiguration为例来分析源码
[Java] 纯文本查看 复制代码
|
01
02
03
04
05
06
07
08
09
10
11
12
|
@Configuration@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@ConditionalOnClass(ServletRequest.class)@ConditionalOnWebApplication(type = Type.SERVLET)@EnableConfigurationProperties(ServerProperties.class)@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class, ServletWebServerFactoryConfiguration.EmbeddedTomcat.class, ServletWebServerFactoryConfiguration.EmbeddedJetty.class, ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })public class ServletWebServerFactoryAutoConfiguration { "… … …"} |
- 其中,@EnableConfigurationProperties(ServerProperties.class)代表加载ServerProperties服务器配置属性类
- 进入ServerProperties.class源码如下
[Java] 纯文本查看 复制代码
|
1
2
3
4
5
6
7
8
|
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)public class ServerProperties { /**Server HTTP port. */ private Integer port; /**Network address to which the server should bind. */ private InetAddress address; … … …} |
更多免费技术资料可关注:annalin1203

浙公网安备 33010602011771号