AI智能
改变未来

深入浅出Spring Boot框架–6个知识点小结!


一、SpringBoot简介

1.什么是SpringBoot

产生背景:Spring开发比较繁琐,配置文件很多,部署流程复杂,整合第三方框架难度大。这会降低开发效率

SpringBoot是一个简化Spring应用创建和开发的框架

整合了整个Spring技术栈,是JavaEE开发一站式解决方案

2.为什么使用SpringBoot

优点:

  • 可以快速构架Spring项目,并与主流框架进行集成
  • 内置Servlet容器,不需要手动部署war包
  • 使用starter管理依赖并进行版本控制
  • 大量自动配置,简化开发
  • 提供准生产环境的运行时监控
  • 不需要XML文件

二、第一个SpringBoot程序

1.操作步骤

步骤:

1.1 创建一个Maven的jar工程

传统的应用需要创建web工程,然后将应用打成war包,然后部署在容器中

而SpringBoot只需要打成一个jar包,其中内置了tomcat

1.2 导入SpringBoot相关依赖

<?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>com.ly</groupId> <artifactId>springboot01-helloworld</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version> </parent> <name>springboot01-helloworld</name> <!-- FIXME change it to the project\'s website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> </build></project>

1.3 创建Controller

package com.ly.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;/** * Author: LuYi * Date: 2019/10/27 11:05 * Description: 描述 */@Controllerpublic class HelloController { @RequestMapping(\"/hello\") @ResponseBody public String hello(){ return \"Hello World\"; }}

1.4 创建启动类

package com.ly;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;/** * Author: LuYi * Date: 2019/10/27 11:05 * Description: 使用@SpringBootApplication将类标注成SpringBoot应用 */@SpringBootApplicationpublic class App { public static void main(String[] args) { SpringApplication.run(App.class, args); }}

默认会扫描@SpringBootApplication注解所在的包及其子包,也可使用@ComponentScan("com.ly.controller")注解进行指定

1.5 打包

<!--该插件可以将应用打包成一个可执行的jar包--><build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins></build>

添加该插件,将应用打成可执行的jar包, 执行:java -jar jar文件

2. 分析HelloWorld

2.1 POM文件

  • 父工程
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.9.RELEASE</version></parent>
  • 父工程的父工程:用来管理SpringBoot应用中依赖的版本,进行版本控制
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.1.9.RELEASE</version> <relativePath>../../spring-boot-dependencies</relativePath></parent>
  • 依赖:通过starter指定依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId></dependency>
  • SpringBoot提供了很多starter(启动器),分别对应了不同的应用场景,当在项目中引入这些starter时,相应场景的依赖就会被导入进来

2.2 启动类

@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})})
  • @SpringBootApplication
  • 标注在类上,表示这个类是SpringBoot的启动类,通过该类的Main方法启动SpringBoot应用
  • @SpringBootConfiguration
  • 标注在类上,表示这个类是SpringBoot的配置类
  • 层级关系:SpringBootConfiguration——>@Configuration——>@Component

    @Configuration:标注在类上,表示这个类是Spring的配置类,相当于XML配置文件

  • @EnableAutoConfiguration
  • 开启自动配置功能,简化了以前繁琐的配置
  • SpringBoot在启动时会在/META-INF/spring.factories中EnableAutoConfiguration指定的值,将这些值作为自动配置类添加到容器中,这些自动配置类会帮我们完成很多配置工作。
  • @ComponentScan
  • 标注在类上,指定要扫描的包及其子包

三、快速创建SpringBoot项目

1.简介

使用Spring initializer快速构建SpringBoot项目

2. 基本操作

  • pom文件和主程序类自动生成,直接写业务逻辑即可
  • resources文件夹的目录结构
|-static    存放静态资源,如js,css,images|-template 存放模板引擎,如freemarker、thymeleaf等|-application.properties   SpringBoot应用的配置文件,可以修改默认设置

四、配置文件

1.简介

SpringBoot的默认全局配置文件有两种:

  • application.properties
  • application.yml

文件名固定,存放在classpath:/或classpath:/config/目录下

可以修改Spring Boot默认配置,具体参考: http://docs.spring.io/spring-boot…

注意:SpringBoot2.0和1.0的配置有区别,有的配置项已被删除

2.YAML用法

2.1 简介

YAML不是一种标记语言,YAML是专门用来写配置文件的,它以数据为中心,简介强大,比xml和properties更适合做配置文件

YAML文件以.yml或.yaml为后置名

2.2 application.yml

server: port: 8081  #写法:key: value 冒号后面必须有空格 servlet: context-path: /springboot03/

2.3 语法规则

  • 大小写敏感
  • 使用缩进表示层级关系
  • 缩进时不允许使用Tab键
  • 缩进的空格数目不重要,但是要与对应的层级的左侧对齐
  • #表示注释

2.4 基本用法

YAML支持的数据结构有三种:

  • 字面量:单个的,不可再分的值(字符串、数字、boolean值)
  • 对象:键值对集合
  • 数组:一组按次序排列的值

三种数据结构的用法:

1.字面量:普通的值,如数字、字符串、布尔值

number: 12.5str: helloname: \'tom cruise\' #如字符串包含空格及特殊字符需要使用 引号 引起来name: \'tom \\n cruise\' #不会对特殊字符进行转义 结果为:tom 换行 cruisename: \"tom \\n cruise\" #对特殊字符进行转义,会作为普通字符输出, 结果为 tom \\n cruise
  1. 对象,也成为映射Map,包含属性和值
# 写法1:换行写user: name: tom age: 20 sex: male # 写法2:行内写法user: {name: tom, age: 20, sex: male}
  1. 数组,如List、Set等
# 写法1: 一组短横线开头的行names:  - tom - jack - alice # 写法2: 行内写法name: {tom,jack,alice}

3. 为属性注入值

通过加载配置文件,为类中的属性注入值

3.1 编写application.yml

user: username: admin age: 21 status: true birthday: 2019/2/14 address: province: 黑龙江省 city: 哈尔滨市 lists: - list1 - list2 - list3 maps: {k1: v1,k2: v2}

3.2 创建实体类

User

package com.luyi.bean;import org.springframework.boot.context.properties.ConfigurationProperties;import org.springframework.stereotype.Component;import java.util.Date;import java.util.List;import java.util.Map;/** * Author: LuYi * Date: 2019/10/27 13:49 * Description: 通过加载配置文件为当前类中的属性注入值 */// 必须将当前类加入到容器@Component// 默认读取全局配置文件获取值,当前类中的所有属性与 user 进行绑定@ConfigurationProperties(value = \"user\")public class User { private String username; private Integer age; private Boolean status; private Date birthday; private Address address; private List<String> lists; private Map<String, Object> maps; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Boolean getStatus() { return status; } public void setStatus(Boolean status) { this.status = status; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } public List<String> getLists() { return lists; } public void setLists(List<String> lists) { this.lists = lists; } public Map<String, Object> getMaps() { return maps; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } @Override public String toString() { return \"User{\" + \"username=\'\" + username + \'\\\'\' + \", age=\" + age + \", status=\" + status + \", birthday=\" + birthday + \", address=\" + address + \", lists=\" + lists + \", maps=\" + maps + \'}\'; }}

Address

package com.luyi.bean;/** * Author: LuYi * Date: 2019/10/27 13:50 * Description: 描述 */public class Address { private String province; private String city; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public String getCity() { return city; } public void setCity(String city) { this.city = city; } @Override public String toString() { return \"Address{\" + \"province=\'\" + province + \'\\\'\' + \", city=\'\" + city + \'\\\'\' + \'}\'; }}

3.3 测试

package com.luyi.springboot03config;import com.luyi.bean.User;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;@SpringBootTestclass Springboot03ConfigApplicationTests { @Autowired private User user; @Test void contextLoads() { System.out.println(user); }}

3.4 添加配置文件处理器依赖(可选)

<!--配置文件处理器,自动生成元数据信息,编写配置文件会有提示--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional></dependency>

3.5 使用properties配置文件

user.username=aliceuser.age=22user.status=falseuser.birthday=2019/10/27user.address.province=黑龙江省user.address.city=哈尔滨user.lists=list1,list2,list3user.maps.k1=v1user.maps.k2=v2

注意:在IDEA中默认使用UTF-8编码,properties文件默认使用ASCII编码,所以会出现乱码,可通过勾选解决

优先级:properties > yml

3.6 使用@Value注解注入值

@Value(\"${user.username}\")private String username;@Value(\"${user.age}\")private Integer age;@Value(\"${user.status}\")private Boolean status;@Value(\"${user.birthday}\")private Date birthday;//@Value不支持复杂类型封装private Address address;@Value(\"${user.lists}\")private List<String> lists;private Map<String, Object> maps;

@Value与@ConfigurationProperties比较:

  • 前者只可以单值注入,后者可以批量8000注入
  • 前者不支持为复杂类型封装,后者支持

4.多环境配置

可以为不同环境提供不同配置信息,如开发环境、测试环境、生产环境等

两种方式:

  • 创建多个properties文件
  • 定义yml文档块

4.1 创建多个properties文件

步骤:

1.创建不同环境的properties文件

文件命名必须符合aplication-xxx.properties的格式

application-dev.properties

server.port=9991

application-test.properties

server.port=9992

application-prod.properties

server.port=9993

2.在application.properties中指定需要激活的配置

#指定要激活的配置spring.profiles.active=prod

4.2 定义yml文档块

1.在yml中使用三个短横线定义多个文档块

spring: profiles: devserver: port: 9991---spring: profiles: testserver: port: 9992---spring: profiles: prodserver: port: 9993

2.在第一个文档块指定要激活的环境

spring: profiles: active: test---

5.加载外部配置文件

5.1 加载properties属性文件

问题:@ConfigurationProperties默认是从全局配置文件中读取值,如果想自定义属性文件中获取值怎么办?

解决:使用@PropertySource注解加载外部属性文件

// 必须将当前类加入到容器@Component//加载外部的属性文件@PropertySource({\"classpath:user.properties\"})// 默认读取全局配置文件获取值,当前类中的所有属性与 user 进行绑定@ConfigurationProperties(value = \"user\")public class User{

5.2 加载spring配置文件

问题:如果有信息需要写道xml文件中,想加载xml文件怎么办

解决:使用@ImportResource加载外部配置文件

5.3 使用注解方式添加组件

推荐使用全注解方式向Spring容器添加组件,@Configuration和@Bean

/** * Author: LuYi * Date: 2019/10/28 14:49 * Description: 描述 *///添加在类上,表示这个类是一个配置类,相当于spring配置文件@Configurationpublic class SpringConfig { //标注在方法上,用来向容器中添加组件,将方法的返回值添加到容器中,方法名作为bean的id @Bean public Address address(){ Address address = new Address(); address.setProvince(\"山东\"); address.setCity(\"日照\"); return address; }}

五、SpringBoot自动配置原理

1.执行流程

1.SpringBoot启动时加载主配置类,使用@EnableAutoConfiguration开启了自动配置功能

2.@EnableAutoConfiguration中使用了 @Import({AutoConfigurationImportSelector.class})向容器中添加了一些组件(自动配置类)

查看AutoConfigurationImportSelector类中的selectImports方法,再点击getAutoConfigurationEntry方法中的`getCandidateConfigurations方法

通过getCandidateConfigurations中的loadFactoryNames方法加载到SpringFactory,

再通过classLoader加载META-INF/spring.factories的配置,从配置中获取EnableAutoConfiguration(spring-boot-autoconfigure-2.1.9.RELEASE.jar)对应的值。

将这些自动配置类(xxxAutoConfiguration)添加到容器中

3.通过自动配置类完成自动配置功能。

2. 原理分析

以HttpEncodingAutoConfiguration为例,就是以前在web.xml中配置的CharacterEncodingFilter过滤器

//表示这是一个配置类,相当于以前编写的Spring配置文件@Configuration//启用HttpProperties类的ConfigurationProperties功能,通过配置文件为属性注入值,并将其添加到容器中@EnableConfigurationProperties({HttpProperties.class})//当该应用是web应用时才生效@ConditionalOnWebApplication( type = Type.SERVLET)//必须包含CharacterEncodingFilter类才生效@ConditionalOnClass({CharacterEncodingFilter.class})//如果配置文件中有spring.http.encoding选项则该配置生效,否则不生效。但是默认已经生效了@ConditionalOnProperty( prefix = \"spring.http.encoding\", value = {\"enabled\"}, matchIfMissing = true)public class HttpEncodingAutoConfiguration { private final Encoding properties;   //将容器中的HttpProperties注入 public HttpEncodingAutoConfiguration(HttpProperties properties) { this.properties = properties.getEncoding(); } //将返回的filter添加到容器中,作为bean @Bean //如果容器中没有这个bean才会生效 @ConditionalOnMissingBean public CharacterEncodingFilter characterEncodingFilter() { CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter(); filter.setEncoding(this.properties.getCharset().name()); filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST)); filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE)); return filter; } //从配置文件中获取指定的值,然后绑定到指定的属性值@ConfigurationProperties( prefix = \"spring.http\")public class HttpProperties { private Charset charset; private Boolean force; private Boolean forceRequest; private Boolean forceResponse; private Map<Locale, Charset> mapping;

注意:

  • 根据当前情况进行判断,决定配置类是否生产,如果不满足条件自动配置就不会生效
  • 自动配置类xxAutoConfiguration的属性是从对应的xxProperties类中获取
  • xxProperties类中的信息是通过配置文件注入绑定的,可以通过配置文件指定属性的值

3.总结

  • SpringBoot在启动时会加载大量的自动配置类
  • 通过自动配置了向容器中添加组件
  • 通过这些组件自动完成许多功能,从而简化配置

可以通过开启debug模式查看自动配置类的匹配情况

#开启debug模式debug=true

六、Web开发

1.简介

使用SpringBoot开发Web应用的步骤:

1.创建SpringBoot项目,添加对应的starter

2.在配置文件中指定必要的少量配置

3.编写业务代码

Web开发的自动配置类WebMvcAutoConfiguration

2.关于静态资源的映射

2.1 静态资源的位置

查看WebMvcAutoConfiguration——>addResourceHandlers()——>getStaticLocations()——>staticLocations

静态资源的默认位置

\"classpath:/META-INF/resources/\",\"classpath:/resources/\", \"classpath:/static/\", \"classpath:/public/\"

可以通过上面的文件夹可以访问到静态资源

也可以在配置文件中自己指定可以访问的位置

# 指定静态资源的位置 存放在根目录下的public文件夹中spring.resources.static-locations=classpath:/public

2.2 欢迎页

查看WebMvcAutoConfiguration—>welcomePageHandlerMapping()—>getWelcomePage()

将index.html页面放到任意一个静态资源文件夹中的

2.3 网站图标

查看WebMvcAutoConfiguration—>内部类FaviconConfiguration—>faviconHandlerMapping

将favicon.ico放到静态资源的任意文件夹中即可

springboot面试题、以及Spring Boot 学习笔记完整教程 关注关注:麒麟改bug,获取。

赞(0) 打赏
未经允许不得转载:爱站程序员基地 » 深入浅出Spring Boot框架–6个知识点小结!