千鹤喵绫 我是大力水手,我喜欢吃菠菜,因此我力大无比!《大力水手》
歌曲封面 未知作品

网站已运行 197 天 8 小时 1 分

Powered by Typecho & Sunny

2 online · 65 ms

Title

Spring Boot入门

千鹤喵绫

·

Article

一、

1、Spring Boot简介

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。

2、微服务

微服务:架构风格(服务微化)

一个应用应该是一组小型服务,可以通过HTTP的方式进行互通

单体应用:ALL IN ONE

微服务:每个功能元素最终都是一个可以独立替换和升级的软件单元

3、环境准备

环境约束

  • jdk1.8
  • maven 3.x :maven3.3以上
  • IDEA2017
  • SpringBoot 1.5.9RELEASE

1、MAVEN设置

♾️ java 代码:
<!-- 配置JDK版本 -->
<profile>    
    <id>jdk18</id>    
    <activation>    
        <activeByDefault>true</activeByDefault>    
        <jdk>1.8</jdk>    
    </activation>    
    <properties>    
        <maven.compiler.source>1.8</maven.compiler.source>    
        <maven.compiler.target>1.8</maven.compiler.target>    
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>    
    </properties>     
</profile>
   <!-- 当 nexus-aliyun 下不了的包,或许这个镜像能下,
        才开放它,这个实在太慢,而且要把它放在首位,即 nexus-aliyun 之前,做过测试。
        所以它的用途只有那么一瞬间,就是或许它能下载,可以通过 url 去查找确定一下
    -->
    <!-- <mirror>
        <id>spring-libs-milestone</id>
        <mirrorOf>central</mirrorOf>
        <name>Spring Milestones</name>
        <url>http://repo.spring.io/libs-milestone</url>
    </mirror> -->

    <!-- nexus-aliyun 首选,放第一位,有不能下载的包,再去做其他镜像的选择  -->
    <mirror>
        <id>nexus-aliyun</id>
        <mirrorOf>central</mirrorOf>
        <name>Nexus aliyun</name>
        <url>http://maven.aliyun.com/nexus/content/groups/public</url>
    </mirror>

    <!-- 备选镜像,也是可以通过 url 去查找确定一下,
        该镜像是否含有你想要的包,它比 spring-libs-milestone 快  -->
    <mirror>
        <id>central-repository</id>
        <mirrorOf>*</mirrorOf>
        typor<name>Central Repository</name>
        <url>http://central.maven.org/maven2/</url>
    </mirror>  

2、IDEA设置

​ 配置IDEA的Maven,指定Setting的Maven目录和MAVEN的setting.xml文件

​ 快捷键:

​ Ctrl+D 复制一行

​ Ctrl+Y 删除一行

​ Ctrl+P 参数提示

​ Ctrl+Alt+V 自动补齐方法

​ Ctrl+N 查找类方法

​ Alt+Ins 构造器、getter/setter toString

​ Ctrl+O 重载方法提示

​ Alt+Enter 提示导入类etc

​ Shift+F6 :文件重命名

4、Spring Boot的Hello World

1、创建一个Maven工程

2、导入Spring Boot的相关依赖

♾️ java 代码:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>           

3、编写个主程序

♾️ java 代码:
@SpringBootApplication
public class SpringBoot01HelloQuickApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot01HelloQuickApplication.class, args);
    }
}

4、编写相应的Controller和Service

♾️ java 代码:
@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public  String  hello(){
        return "hello world";
    }
}          

5、运行主程序测试

访问 localhost:8080/hello

6、简化部署

在pom.xml文件中,导入build插件

♾️ java 代码:
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

5、HelloWorld深度理解

1.POM.xml文件

1、父项目

♾️ xml 代码:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>       

这个父项目spring-boot-starter-parent又依赖一个父项目

♾️ xml 代码:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

下面有个属性,定义了对应的版本号

♾️ xml 代码:
<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>

Spring Boot的版本仲裁中心 会自动导入对应的版本,不需要我们自己导入依赖,没有dependencies里面管理的依赖自己声明

2、启动器

♾️ xml 代码:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-web:帮我们导入web模块正常运行所依赖的组件

spring boot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目里引入这些starter相关场景的所有依赖都会被导入进来,要用什么功能就导入什么场景的启动器。

2、主程序入口

♾️ java 代码:
@SpringBootApplication
public class SpringBoot01HelloQuickApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot01HelloQuickApplication.class, args);
    }
}

@SpringBootApplication: 说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动应用

进入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 {}

@SpringBootConfiguration:SpringBoot的配置类: 标准在某个类上,表示这是一个SpringBoot的配置类

@Configuration:配置类上,来标注这个注解; 配置类 ---- 配置文件,也是容器中的一个组件(@Component) @EnableAutoConfiguration:开启自动配置功能 以前需要自动配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动 配置功能;这样自动配置才能生效。

♾️ java 代码:
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {  }

@AutoConfigurationPackage:自动配置包 @Import({Registrar.class}):底层注解,给容器导入组件; 将主配置类(@SpringBootApplication标注的类)的所在包及下面所有的子包里面的所有组件扫描到Spring容器;

@Import({AutoConfigurationImportSelector.class}): 给容器导入组件?

AutoConfigurationImportSelector:导入组件选择器

将所有需要导入的组件以及全类名的方式返回;这些组件将以字符串数组 String[] 添加到容器中;

会给容器非常多的自动配置类,(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置 好这些组件。

image-20240415171951538♾️ java 代码:
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;
} 

SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());

Spring Boot在启动的时候从类路径下的META-INF/spring.factorys中获取的EnableAutoConfiguration指定的值;

将这些值作为自动配置类导入到容器中,自动配置就生效了。

image-20240415172121573

J2EE的整体解决方案

org\springframework\boot\spring-boot-autoconfigure\2.0.1.RELEASE\spring-boot-autoconfigure-2.0.1.RELEASE.jar

6、使用Spring Initializer创建一个快速向导

1.IDE支持使用Spring Initializer

自己选择需要的组件:例如web

默认生成的SpringBoot项目

  • 主程序已经生成好了,我们只需要完成我们的逻辑
  • resources文件夹目录结构
    • static:保存所有的静态文件;js css images
    • templates:保存所有的模板页面;(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP);可

以使用模板引擎(freemarker.thymeleaf);

    • application.properties:Spring Boot的默认配置,例如 server.port=9000

二、配置文件

1、配置文件

Spring Boot使用全局配置文件,配置文件名是固定的;

  • application.properties
  • application.yml

配置文件作用:修改Spring Boot在底层封装好的默认值;

YAML(YAML AIN'T Markup Language)

是一个标记语言

又不是一个标记语言

标记语言:

以前的配置文件;大多数使用的是 xxx.xml文件;

以数据为中心,比json、xml等更适合做配置文件

YAML:配置例子

♾️ yaml 代码:
server: 
  port: 9000

XML:

♾️ xml 代码:
<server>
    <port>9000</port>
</server>

2、YAML语法

1、基本语法

k:(空格)v:表示一堆键值对(空格必须有);

以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一层级的

♾️ yaml 代码:
server:
    port: 9000
    path: /hello 

属性和值也是大小写敏感

2、值的写法

字面量:普通的值(数字,字符串,布尔)

k: v:字面直接来写;

字符串默认不用加上单引号或者双引号

"":双引号 不会转义字符串里的特殊字符;特殊字符会作为本身想要表示的意思

name:"zhangsan\n lisi" 输出:zhangsan换行 lisi

'':单引号 会转义特殊字符,特殊字符最终只是一个普通的字符串数据

name:'zhangsan\n lisi' 输出:zhangsan\n lisi

对象、Map(属性和值)键值对

k :v :在下一行来写对象的属性和值的关系;注意空格控制缩进

对象还是k:v的方式

♾️ yaml 代码:
frends:
    lastName: zhangsan
    age: 20 

行内写法

♾️ text 代码:
friends: {lastName: zhangsan,age: 18} 

数组(List、Set): 用-表示数组中的一个元素

♾️ xml 代码:
pets:
 ‐ cat
 ‐ dog
 ‐ pig                           

行内写法

♾️ xml 代码:
pets: [cat,dog,pig] 

组合变量

多个组合到一起

3、配置文件值注入

1、@ConfigurationProperties

1、application.yml 配置文件

♾️ yml 代码:
person:
  age: 18
  boss: false
  birth: 2017/12/12
  maps: {k1: v1,k2: 12}
  lists:
   - lisi
   - zhaoliu
  dog:
    name: wangwang
    age: 2
  last-name: wanghuahua

application.properties 配置文件(二选一)

♾️ properties 代码:
idea配置文件utf-8
properties 默认GBK
person.age=12
person.boss=false
person.last-name=张三
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=wanghuahu
person.dog.age=15

所以中文输出乱码,改进settings-->file encoding -->[property-->utf-8 ,勾选转成ascii]

javaBean

♾️ java 代码:
/**
* 将配置文件的配置每个属性的值,映射到组件中
* @ConfigurationProperties:告诉SpringBoot将文本的所有属性和配置文件中的相关配置进行绑定;
* prefix = "person" 配置文件爱你的那个属性进行一一映射
* *
只有这个组件是容器中的组件,才能提供到容器中
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String lastName;
    private Integer age;
    private Boolean boss;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

导入配置文件处理器,以后编写配置就有提示了

♾️ xml 代码:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring‐boot‐configuration‐processor</artifactId>
    <optional>true</optional>
</dependency>  

2、@Value注解

更改javaBean中的注解

♾️ java 代码:
@Component
public class Person {
    /**
     * <bean class="Person">
     *     <property name="lastName" value="字面量/${key}从环境变量/#{spEL}"></property>
     * </bean>
     */
    @Value("${person.last-name}")
    private String lastName;
    @Value("#{11*2}")
    private Integer age;
    @Value("true")
    private Boolean boss;

@ConfigurationProperties@Value
功能批量注入配置文件属性单个指定
松散绑定(语法)支持不支持
spEL不支持支持
JSR303校验支持不支持
复杂类型支持不支持

松散语法:javaBean中last-name(或者lastName) -->application.properties中的last-name;

spEL语法:#{11*2}

JSR303:@Value会直接忽略,校验规则

JSR303校验:

♾️ java 代码:
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    @Email
    private String lastName;

复杂类型栗子:

♾️ java 代码:
@Component
public class Person {
    /**
     * <bean class="Person">
     *     <property name="lastName" value="字面量/${key}从环境变量/#{spEL}"></property>
     * </bean>
     */
    private String lastName;
    private Integer age;
    private Boolean boss;
   // @Value("${person.maps}")
    private Map<String,Object> maps;

以上会报错,不支持复杂类型

使用场景分析

​ 如果说,我们只是在某个业务逻辑中获取一下配置文件的某一项值,使用@Value;

如果专门编写了一个javaBean和配置文件进行映射,我们直接使用@ConfigurationProperties

举栗子:

1、编写新的Controller文件

♾️ java 代码:
@RestController
public class HelloController {

    @Value("${person.last-name}")
    private String name;
    @RequestMapping("/hello")
    public  String sayHello(){
        return "Hello"+ name;
    }
}

2、配置文件

♾️ properties 代码:
person.age=12
person.boss=false
person.last-name=李四
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=wanghuahu
person.dog.age=15

3、测试运行

访问 localhost:9000/hello

结果为Hello 李四

3、其他注解

@PropertySource

作用:加载指定的properties配置文件

1、新建一个person.properties文件

♾️ properties 代码:
person.age=12
person.boss=false
person.last-name=李四
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=wanghuahu
person.dog.age=15

2、在javaBean中加入@PropertySource注解

♾️ java 代码:
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
   private String lastName;

@ImportResource

作用:导入Spring配置文件,并且让这个配置文件生效

1、新建一个Spring的配置文件,bean.xml

♾️ xml 代码:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="HelloService" class="com.wdjr.springboot.service.HelloService"></bean>
</beans>

2、编写测试类,检查容器是否加载Spring配置文件写的bean

♾️ java 代码:
@Autowired
ApplicationContext ioc;

@Test
public void testHelloService(){
   boolean b = ioc.containsBean("HelloService");
   System.out.println(b);
}

3、运行检测

结果为false,没有加载配置的内容

4、使用@ImportResource注解

将@ImportResource标注在主配置类上

♾️ java 代码:
@ImportResource(locations={"classpath:beans.xml"})
@SpringBootApplication
public class SpringBoot02ConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBoot02ConfigApplication.class, args);
    }
}

5、再次运行检测

结果为true

缺点:每次指定xml文件太麻烦

SpringBoot推荐给容器添加组件的方式:

1、配置类=====Spring的xml配置文件(old)

2、全注解方式@Configuration+@Bean(new)

image-20240415173237228

♾️ java 代码:
/**
 * @Configuration:指明当前类是一个配置类;就是来代替之前的Spring配置文件
 *
 * 在配置文件中用<bean></bean>标签添加组件
 */

@Configuration
public class MyAppConfig {

    //将方法的返回值添加到容器中;容器这个组件id就是方法名
    @Bean
    public HelloService helloService01(){
        System.out.println("配置类给容器添加了HelloService组件");
        return new HelloService();
    }
}

♾️ java 代码:
@Autowired
ApplicationContext ioc;

@Test
public void testHelloService(){
    boolean b = ioc.containsBean("helloService01");
    System.out.println(b);
}

容器这个组件id就是方法名

4、配置文件占位符

1、随机数

♾️ java 代码:
${random.value} 、${random.int}、${random.long}
${random.int(10)}、${random.int[100,200]}

2、获取配置值

♾️ properties 代码:
person.age=${random.int}
person.boss=false
person.last-name=张三${random.uuid}
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=${person.last-name}'s wanghuahu
person.dog.age=15

存在以下两种情况

没有声明person.last-name会报错,新声明的需要加默认值

♾️ properties 代码:
person.age=${random.int}
person.boss=false
person.last-name=张三${random.uuid}
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=${person.hello:hello}'s wanghuahu
person.dog.age=15

结果:输出hello's wanghuahua

5、Profile

1、多Profile文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml

  • application.properties
  • application-dev.properties
  • application-prod.properties

默认使用application.properties

application.properties配置文件指定

♾️ text 代码:
spring.profiles.active=dev

2、YAML文档块

♾️ yaml 代码:
server:
port: 8081
spring:
profiles:
  active: dev

---

server:
port: 9000
spring:
profiles: dev

---
server:
port: 80
spring:
profiles: prod

3、激活指定profile

1、在配置文件中激活

2、命令行:

--spring.profiles.active=dev

image-20240415173558225

优先级大于配置文件

打包 成jar后

java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev

虚拟机参数

-Dspring.profiles.active=dev

6、加载配置文件位置

SpringBoot启动扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件

  • file:./config/
  • file./
  • classpath:/config/
  • classpath:/

优先级从高到低顺序,高优先级会覆盖低优先级的相同配置;互补配置

也可以通过spring.config.location来改变默认配置

♾️ text 代码:
server.servlet.context-path=/boot03   

注:spring boot1x 是server.context.path=/boot02

image-20240415173652176

还可以通过spring.config.location来改变配置文件的位置

项目打包好了以后,可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认的配置文件会共同起作用,互补配置

java -jar spring-boot-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=E:/work/application.properties

运维比较有用,从外部加载,不用修改别的文件

7.引入外部配置

SpringBoot也可以从以下位置加载配置;优先级从高到低;高优先级覆盖低优先级,可以互补

  1. 命令行参数

java -jar spring-boot-config-02-0.0.1-SNAPSHOT.jar --server.port=9005 --server.context-path=/abc

中间一个空格

  1. 来自java:comp/env的JNDI属性
  2. java系统属性(System.getProperties())
  3. 操作系统环境变量
  4. RandomValuePropertySource配置的random.*属性值

优先加载profile, 由jar包外到jar包内

  1. jar包外部的application-{profile}.properties或application.yml(带Spring.profile)配置文件
  2. jar包内部的application-{profile}.properties或application.yml(带Spring.profile)配置文件
  3. jar包外部的application.properties或application.yml(带Spring.profile)配置文件
  4. jar包内部的application.properties或application.yml(不带spring.profile)配置文件
  5. @Configuration注解类的@PropertySource
  6. 通过SpringApplication.setDefaultProperties指定的默认属性

[官方文档]

8、自动配置

配置文件到底怎么写?

Spring的所有配置参数

自动配置原理很关键

1、自动配置原理

1)、SpringBoot启动的时候加载主配置类,开启自动配置功能,@EnableAutoConfiguration

2)、@EnableAutoConfiguration 作用:

  • 利用AutoConfigurationImportSelector给容器中导入一些组件?
  • 可以查看selectImports()方法的内容
  • 获取候选的配置

♾️ text 代码:
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);

  • 扫描类路径下的
♾️ java 代码:
 SpringFactoriesLoader.loadFactoryNames()
 扫描所有jar包类路径下的 MATA-INF/spring.factories
 把扫描到的这些文件的内容包装成properties对象
 从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加到容器中

将类路径下 MATE-INF/spring.factories里面配置的所有的EnableAutoConfiguration的值加入到了容器中;

3)、每一个自动配置类进行自动配置功能;

4)、以HttpEncodingAutoConfiguration 为例

♾️ java 代码:
@Configuration //表示是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties({HttpEncodingProperties.class})//启动指定类的Configurationproperties功能;将配置文件中的值和HttpEncodingProperties绑定起来了;并把HttpEncodingProperties加入ioc容器中
@ConditionalOnWebApplication//根据不同的条件,进行判断,如果满足条件,整个配置类里面的配置就会失效,判断是否为web应用;
(
    type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class})//判断当前项目有没有这个类,解决乱码的过滤器
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)//判断配置文件是否存在某个配置 spring.http.encoding,matchIfMissing = true如果不存在也是成立,即使不配置也生效
public class HttpEncodingAutoConfiguration {
   //给容器添加组件,这个组件的值需要从properties属性中获取
    private final HttpEncodingProperties properties;
    //只有一个有参数构造器情况下,参数的值就会从容器中拿
    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
        this.properties = properties;
    }

    @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.HttpEncodingProperties.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpEncodingProperties.Type.RESPONSE));
        return filter;
    }

5)、所有在配置文件中能配置的属性都是在xxxProperties类中封装着;配置文件能配置什么就可以参照某个功能对应的这个属性类

♾️ java 代码:
@ConfigurationProperties(prefix = "spring.http.encoding")//从配置文件中的值进行绑定和bean属性进行绑定
public class HttpEncodingProperties {}

根据当前不同条件判断,决定这个配置类是否生效?

一旦这个配置类生效;这个配置类会给容器添加各种组件;这些组件的属性是从对应的properties中获取的,这些类里面的每个属性又是和配置文件绑定的

2、所有的自动配置组件

每一个xxxAutoConfiguration这样的类都是容器中的一个组件,都加入到容器中;

作用:用他们做自动配置

♾️ text 代码:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.reactor.core.ReactorCoreAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
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,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration

3、精髓:

1)、SpringBoot启动会加载大量的自动配置类

2)、我们看我们需要的功能有没有SpringBoot默认写好的默认配置类;

3)、如果有在看这个自动配置类中配置了哪些组件;(只要我们要用的组件有,我们需要再来配置)

4)、给容器中自动配置添加组件的时候,会从properties类中获取属性。我们就可以在配置文件中指定这些属性的值

xxxAutoConfiguration:自动配置类;

给容器中添加组件

xxxProperties:封装配置文件中的属性;

跟之前的Person类一样,配置文件中值加入bean中

4、细节

1、@Conditional派生注解

利用Spring注解版原生的@Conditional作用

作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;

@Conditional派生注解作用(判断是否满足当前指定条件)
@ConditionalOnJava系统的java版本是否符合要求
@ConditionalOnBean容器中存在指定Bean
@ConditionalOnMissBean容器中不存在指定Bean
@ConditionalOnExpression满足spEL表达式
@ConditionalOnClass系统中有指定的类
@ConditionalOnMissClass系统中没有指定的类
@ConditionalOnSingleCandidate容器中只有一个指定的Bean,或者这个Bean是首选Bean
@ConditionalOnProperty系统中指定的属性是否有指定的值
@ConditionalOnResource类路径下是否存在指定的资源文件
@ConditionalOnWebApplication当前是web环境
@ConditionalOnNotWebApplication当前不是web环境
@ConditionalOnJndiJNDI存在指定项

2、自动配置报告

自动配置类必须在一定条件下生效

我们可以通过启用debug=true属性,配置文件,打印自动配合报告,这样就可以知道自动配置类生效

♾️ text 代码:
debug=true

自动配置报告

♾️ java 代码:
============================

CONDITIONS EVALUATION REPORT
============================


Positive matches:(启动的,匹配成功的)
-----------------

  CodecsAutoConfiguration matched:
     - @ConditionalOnClass found required class 'org.springframework.http.codec.CodecConfigurer'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      ......
       
Negative matches:(没有启动的,没有匹配成功的)
-----------------

  ActiveMQAutoConfiguration:
     Did not match:
        - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

.....

三、日志

Spring Boot2对日志有更改

1、日志框架

小张:开发一个大型系统;

1、System.out.println("");将关键数据打印在控制台;去掉?卸载文件中

2、框架记录系统的一些运行信息;日志框架zhanglog.jar

3、高大上功能,异步模式?自动归档?xxx?zhanglog-good.jar?

4、将以前的框架卸下来?换上新的框架,重新修改之前的相关API;zhanglog-perfect.jar;

5、JDBC--数据库驱动;

​ 写了一个统一的接口层;日志门面(日志的一个抽象层);logging-abstract.jar;

​ 给项目中导入具体的日志实现就行;我们之前的日志框架都是实现的抽象层;

市面上的日志框架

日志抽象层日志实现
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for Java) jboss-loggingLog4j JUL(java.util.logging) Log4j2 Logback

左边的抽象,右边的实现

SLF4J -- Logback

Spring Boot:底层是Spring框架,Spring默认框架是JCL;

​ SpringBoot选用SLF4J和logback

2、SLF4J使用

1、如何在系统中使用SLF4j

以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法;

应该给系统里面导入slf4j的jar包和logback的实现jar

♾️ java 代码:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
 public static void main(String[] args) {
   Logger logger = LoggerFactory.getLogger(HelloWorld.class);
   logger.info("Hello World");
}
}

image-20240415174215340

每个日志框架的实现框架都有自己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架本身的配置文件

2、遗留问题

a系统(slf4j+logback):Spring(commons-logging)、Hibernate(jboss-logging)、Mybatis

统一日志框架,即使是别的框架和我一起统一使用slf4j进行输出;

核心:

1、将系统中其他日志框架排除出去;

2、用中间包来替换原有的日志框架/

3、导入slf4j的其他实现

3、SpingBoot日志框架解析

打开IDEA ,打开pom文件的依赖图形化显示

image-20240415174228224

SpringBoot的基础框架

♾️ java 代码:
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

SpringBoot的日志功能

♾️ text 代码:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
    <version>2.0.1.RELEASE</version>
    <scope>compile</scope>
</dependency>

image-20240415174402839

总结:

  1. SpringBoot底层也是使用SLF4J+log4jback
  2. SpringBoot也把其他日志替换成了slf4j
  3. 起着commons.loggings的名字其实new的SLF4J替换中间包

SpringBoot2中改成了bridge

  1. 如果要引入其他框架?一定要把这个框架的日志依赖移除掉,而且底层

4、日志的使用

1、默认配置

trace-debug-info-warn-error

可以调整需要的日志级别进行输出,不用注释语句。

♾️ java 代码:
//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
   //日志的级别
   //从低到高
   //可以调整输出的日志级别;日志就只会在这个级别以后的高级别生效
   logger.trace("这是trace日志");
   logger.debug("这是debug信息");
   //SpringBoot默认给的是info级别,如果没指定就是默认的root级别
   logger.info("这是info日志");
   logger.warn("这是warn信息");
   logger.error("这是Error信息");
}  

调整指定包的日志级别在配置文件中进行配置

♾️ java 代码:
logging.level.com.wdjr=trace

日志输出格式

♾️ text 代码:
#控制台输出的日志格式
#%d:日期
#%thread:线程号
#%-5level:靠左 级别
#%logger{50}:全类名50字符限制,否则按照句号分割
#%msg:消息+换行
#%n:换行
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

SpringBoot修改日志的默认配置

♾️ text 代码:
logging.level.com.wdjr=trace
#不指定path就是当前目录下生成springboot.log
#logging.file=springboot.log
#当前磁盘下根路径创建spring文件中log文件夹,使用spring.log作为默认
logging.path=/spring/log
#控制台输出的日志格式 日期 + 线程号 + 靠左 级别 +全类名50字符限制+消息+换行
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
#指定文件中日志输出的格式
logging.pattern.file=xxx

2、指定配置

给类路径下放上每个日志框架自己的配置框架;SpringBoot就不会使用自己默认的配置

logging SystemCustomization
Logbacklogback-spring.xml ,logback-spring.groovy,logback.xml or logback.groovy
Log4J2log4j2-spring.xml or log4j2.xml
JDK(Java Util Logging)logging.properties

logback.xml直接被日志框架识别 ,logback-spring.xml日志框架就不直接加载日志配置项,由SpringBoot加载

♾️ text 代码:
<springProfile name="dev">
<!-- 可以指定某段配置只在某个环境下生效 -->
</springProfile>
<springProfile name!="dev">
<!-- 可以指定某段配置只在某个环境下生效 -->
</springProfile>

如何调试开发环境,输入命令行参数

--spring.profiles.active=dev

如果不带后面的xx-spring.xml就会报错

3、切换日志框架

可以根据slf4j的日志适配图,进行相关切换;

1、log4j

slf4j+log4j的方式;

image-20240415174759545♾️ text 代码:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
</dependency>

不推荐使用仅作为演示

2、log4j2

切换为log4j2

♾️ text 代码:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-logging</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

四、web开发

1、简介

使用SpringBoot;

1)、创建SpringBoot应用,选中我们需要的模块;

2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来

3)、自己编写业务代码

自动配置原理?

这个场景的SpringBoot帮我们配置了什么?能不能修改?能修改那些配置?能不能扩展?xxx

♾️ text 代码:
xxxAutoConfiguration:帮我们给容器中自动配置组件
xxxProperties:配置类来封装配置文件的内容

2、静态资源文件映射规则

♾️ java 代码:
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties implements ResourceLoaderAware, InitializingBean {
    //可以设置和静态资源相关的参数,缓存时间等

♾️ java 代码:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
   if (!this.resourceProperties.isAddMappings()) {
      logger.debug("Default resource handling disabled");
      return;
   }
   Integer cachePeriod = this.resourceProperties.getCachePeriod();
   if (!registry.hasMappingForPattern("/webjars/**")) {
      customizeResourceHandlerRegistration(registry
            .addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/")
            .setCachePeriod(cachePeriod));
   }
   String staticPathPattern = this.mvcProperties.getStaticPathPattern();
   if (!registry.hasMappingForPattern(staticPathPattern)) {
      customizeResourceHandlerRegistration(
            registry.addResourceHandler(staticPathPattern)
                  .addResourceLocations(
                        this.resourceProperties.getStaticLocations())
                  .setCachePeriod(cachePeriod));
   }
}

广告

页底广告 页底广告
此页面评论区已关闭
搜 索 消 息 足 迹
你还不曾留言过..
你还不曾留下足迹..
博主