SpringBoot 入门与进阶

SpringBoot 入门与进阶


一、SpringBoot 入门

1、SpringBoot 简介

  SpringBoot 是基于Spring4.0设计,用来简化 Spring 应用开发流程的开发框架,它不仅继承了Spring框架原有的优秀特性,而且还通过简化配置来进一步简化了Spring应用的整个搭建和开发过程(约定大于配置)。

2、SpringBoot 的优点:

  • 快速创建独立运行的 Spring 项目并集成主流框架
  • 使用嵌入式的 Servlet 容器,应用不用打成 war 包
  • starters 自动依赖与版本控制
  • 大量的自动配置,简化开发流程
  • 无需配置 XML ,无代码生成,开箱即用
  • 准生产环境的运行时应用监控

3、SpringBoot 创建 HelloWorld

(1)通过 maven 创建 SpringBoot 项目

在这里插入图片描述
在这里插入图片描述

  • 导入 SpringBoot 相关的依赖
    <!-- 导入springboot相关的依赖 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.3.9.RELEASE</version>
        </dependency>
    </dependencies>

    <!-- 这个插件,可以将应用打成一个可执行的 jar 包 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.9.RELEASE</version>
            </plugin>
        </plugins>
    </build>
  • 编写一个主程序,用于启动 SpringBoot 应用
    在这里插入图片描述
  • 编写相关的 Controller或相关业务代码
    在这里插入图片描述
  • 启动 SpringBoot 应用,在浏览器输入:localhost:808/hello 进行测试
    在这里插入图片描述
  • 将项目打成 jar 包
    在这里插入图片描述
  • 在终端运行测试
  • 进入 jar 包所在目录
  • 通过: java -jar springboot-1.0-SNAPSHOT.jar 命令执行
  • 随后在浏览器输入:localhost:8080/hello 测试

在这里插入图片描述
在这里插入图片描述

(2)通过 Spring Initialiar 快速创建 Spring Boot 应用

快速创建 SpringBoot 应用流程:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在创建好的项目中,对其结构进行介绍:
  • “1”:表示当你忘记点击自动导包时,可以点其刷新重新加载包
  • “2”的 static :表示保存所有的静态资源,包括:js、css、image
  • “3”的 templates:表示保存所有的模版页面。(SpringBoot 默认 jar 包使用嵌入式的 Tomcat ,默认不支持 JSP 页面);可以使用模版引擎(freemarker、thymeleaf)
  • “4”的 application.properties:Spring Boot 应用的配置文件,可以修改一些默认配置。例如在里面修改默认端口号:server.port=8081
    在这里插入图片描述

3、SpringBoot 的版本仲裁中心:spring-boot-dependencise

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.9.RELEASE</version>
    </parent>
    
    <!-- 它的父项目如下 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.3.9.RELEASE</version>
        <relativePath>../../spring-boot-dependencies</relativePath>
    </parent>

  spring-boot-dependencies 是管理 Spring Boot 应用里面的所有依赖版本,以后我们导入依赖默认是不需要写版本号的。

4、SpringBoot 场景启动器: spring-boot-starter

  SpringBoot 将所有的功能场景都抽取出来,做成一个个的启动器(starters),只要在项目里引入这些 starter 相关的场景,相关场景的所有依赖都会导入进来。要用什么功能就导入什么场景的启动器,例如:spring-boot-starter-web、spring-boot-starter-security、spring-boot-starter-websocket等。

5、主程序入口类

/**
 * @SpringBootApplication 注解是用来标注一个主程序,说明这是一个 SpringBoot 应用
 */
@SpringBootApplication
public class HelloWorldApplication {
    /**
     * 让 SpringBoot 应用启动起来
     * @param args
     */
    public static void main(String[] args){
        SpringApplication.run(HelloWorldApplication.class,args);
    }
}

@SpringBootApplication 注解:该注解标注在某个类上说明这个类是 SpringBoot 的主配置类,SpringBoot 就应该运行这个类的 main 方法来启动 SpringBoot 应用。

@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 {

@SpringBootApplication 注解是一个组合注解,由以上代码中的注解组成。
其中:
@SpringBootConfiguration 注解: 是 SpringBoot 的配置类,其标注在哪个类上,表示这个类是 SpringBoot 的配置类。
@EnableAutoConfiguration 注解: 是告诉 SpringBoot 开启自动配置功能。

二、SpringBoot 配置

1、配置文件

SpringBoot 使用一个全局的配置文件,配置文件名是固定的,配置文件放在 src/main/resources 目录或者 类路径/config 下:

  • application.properties
  • application.yml

上述配置文件的作用:修改 SpringBoot 在底层给我们自动配置好的默认值。

标记语言:
  以前的配置文件大多使用的是 xxx.xml 文件;
  YAML:以数据为中心,比 json、xml 等更适合做配置文件。

YAML配置示例:

server:
  port: 8081

XML配置示例:

<server>
    <port>8081</port>
</server>

2、YAML 的语法

(1)基本语法

  • 以 k:(空格)v 表示一对键值对,而且空格必须有;
  • 空格 的缩进来控制层级关系;只要在左对齐是同一列都表示同一层级;
server:
  port: 8081
  path: /hello
  • 属性和值都是大小写敏感。

(2)值的写法
普通的值:数字、字符串、布尔
  直接 k:(空格)v
  字符串默认不加单引号或者双引号
    ""双引号:不会转义字符串里面的特殊字符,特殊字符按原来的意思起作用。例如:name:“hello \n world” 实际输出为:hello 换行 world
    ''单引号:会转义字符,特殊字符只当作普通字符处理。例如:‘hello \n world’ 实际输出为:hello \n world

对象、Map的属性和值
直接 k:(空格)v
  正常写法:

server:
  port: 8081
  path: /hello

  写在同一行的写法:

server: {port: 8081,path: /hello}

数组(List、Set)
“-(空格)值” 表示数组中的一个元素
  正常写法:

lists:
  - value1
  - value2
  - value3

  写在同一行的写法:

lists: [value1,value2,value3]

3、配置文件的值注入

(1)值注入之@ConfigurationProperties(prefix=“person”)

application.yml 配置文件的内容

person:
  lastName: zhansan
  age: 18
  maps: {k1: v1,k2: v2}
  lists:
    - list1
    - list2
  man:
    height: 180
    weight:130

java Bean:

/**
* 将配置文件中的配置的每一个属性的值,映射到这个组中
*  @ConfigurationProperties:告诉 SpringBoot 将本类中的所有属性和配置文件中的相关配置进行绑定;
*  prefix = "person":配件文件中哪个对象与下面所有属性进行一一映射
* 只有这个组件是容器中的组件,才能让容器提供 @ConfigurationProperties 的功能
* /
@Component
@ConfigurationProperties(prefix="person")
public class Person {
    private String lastName;
    private Integer age;
    private Man man;
    private List<Object> lists;
    private Map<String,Object> maps;
}

导入配置文件处理器,在编写配置时有提示:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency

(2)值注入之 @Value

/**
* 将配置文件中的配置的每一个属性的值,映射到这个Bean中
*  这里不再使用 @ConfigurationProperties 注解,而将换为 @Value 注解
* @Value(${person.last-name})中“$”表示占位对应,“-name”表示“n”大写
* @Value(#{18+3})中的“#”表示里面可以为表达式
* /
@Component
// @ConfigurationProperties(prefix="person")
public class Person {
    @Value(${person.last-name})
    private String lastName;
    @Value(#{18+3})
    private Integer age;
    private Man man;
    private List<Object> lists;
    private Map<String,Object> maps;
}

(3)@Value 获取值和@ConfigurationProperties 获取值相比较

@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持
  • 配置文件无论是 .yml 还是 .properties 类型,它们都能获取到值。
  • 如果只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用 @Value;
  • 如果获取的值较多,则使用 @ConfigurationProperties 。

(4)application.properties 配置文件乱码

在这里插入图片描述

(5)@PropertySource 和 @ImportREsource

@PropertySource(value={“classpath:文件路径”}) : 加载指定的配置文件;

@ImportREsource(locations = {“classpath:文件路径”}) : 导入 Spring 的配置文件,让配置文件里面的内容生效。想让 Spring 的配置文件生效加载进来,使用 @ImportREsource 注解标注在需要应用配置的配置类上。

(6)@Configuration 和 @Bean

@Configuration: 指明当前类是一个配置类(等同于配置文件),就是用来替代之前的 Spring 配置文件的

@Bean: 是标注在方法上,其作用是将方法的返回值添加到容器中,容器中这个组件的默认 id 就是方法名

4、配置文件占位符

随机数

${random.value}、
${random.int}
${random.long}、
${random.int(10)}
${random.int[100,5000]}等等

占位符获取之前配置的值,如果没有,可以使用“:”指定默认值。
例如:${person.age:18}

5、profile多环境支持

(1)多 profile 文件

  • 我们在主配置编写的时候,文件名可以是:application-{profile}.properties/yml
  • 例如:application-dev.properties 或 application-prod.properties 或 application-dev.yml 或 application-prod.yml
  • 默认使用的是:application.properties 的配置文件。

(2)yml 支持多文档块的方式

yml 使用 “—”对文档进行块划分。

server:
  port: 8080
spring:
  profiles:
    active: dev

---
server:
  port: 8081
spring:
  profiles: dev   #指定属于哪个环境

---
server:
  port: 8082
spring:
  profiles: prod   #指定属于哪个环境

(3)激活制定的 profile

  • 用 spring.profiles.active = dev 在配置文件中指定激活的 profiles,等于谁就激活谁,不指定就使用默认。
  • 命令行方式激活:
      --spring.profiles.active = dev (使用命令行激活的优先级大于配置文件,也就是说,即使配置文件里的是激活prod,命令行激活的是dev,最终的结果也指向dev)
    在这里插入图片描述
      打成 jar 包后在终端该 jar 包目录下输入:java -jar springboot.jar(这是jar包名) --spring.profiles.active = dev(或者等于prod)激活
  • 虚拟机参数方式:
      在 VM options: 中输入:-Dspring.profiles.active=dev 点击OK之后重新启动项目就能激活dev

6、配置文件的加载位置

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

  • file:/config/application.yml (file表示的是项目名)
  • file:/application.yml
  • classpath:/config/application.yml (classpath表示的是resources)
  • classpath:/application.yml

  以上的排列是按照 优先级从高到低 的顺序,所有位置的文件都会被加载,高优先级配置的内容会覆盖低优先级配置的内容
  SpringBoot 会从这四个位置全部加载主配置文件,相同的内容会被高优先级的覆盖,不同的配置内容会互补。

改变默认文件位置:spring.config.location
  我们还可以通过 spring.config.location 来改变默认的文件位置。项目打包好之后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定的配置文件和默认加载的这些配置文件共同起作用形成互补配置。
  例如:java -jar springboot项目名.jar --spring.config.location=配置文件的路径

7、外部配置的加载顺序

  SpringBoot 也可以从以下位置加载配置;优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置。

  • 命令行参数(多个参数用空格分隔)
  • 来自 java:comp/env的 JNDI 属性
  • Java系统属性(System.getProperties())
  • 操作系统环境变量
  • RandomValuePropertySource 配置的 random.* 属性
  • jar 包外部的 application-{profile}.properties 或 application-{profile}.yml(带spring.profile)配置文件
  • jar 包内部的 application-{profile}.properties 或 application-{profile}.yml(带spring.profile)配置文件
  • jar 包外部的 application.properties 或 application.yml(不带spring.profile)配置文件
  • jar 包内部的 application.properties 或 application.yml(不带spring.profile)配置文件
  • @Configuration 注解类上的 @PropertySource
  • 通过 SpringApplication.setDefaultProperties 指定的默认属性

  对于常用的几个(加粗),优先级高的优先,由 jar 包外向 jar 包内进行寻找(先外后内),带 profile 的优先于不带 profile 的。

8、SpringBoot 自动配置原理

(1)自动配置原理

  • SpringBoot 启动的时候加载主配置类,开启了自动配置功能;@SpringBootApplication 是一个组合注解,其里面的 @EnableAutoConfiguration 开启自动配置功能。
  • @EnableAutoConfiguration作用是:利用 EnableAutoConfigurationImportSelector 给容器中导入一些组件,EnableAutoConfigurationImportSelector 的父类AutoConfigurationImportSelector 中有一个方法 SelectImports(),可以通过查看 SelectImports() 方法的内容知道导入哪些组件
  • SelectImports() 方法中的:List configurations = getCandidateConfigurations(annotationMetadata, attributes); 获取候选的配置
  • 而 getCandidateConfigurations()方法里面的
    List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),getBeanClassLoader()); 的作用是扫描所有 jar 包类路径下的 META-INF/spring.factories 文件,把扫描到的这些文件的内容包装成 Properties 对象,从 properties 中获取到 EnableAutoConfiguration.class 类名对应的值,然后把它们添加到容器中。(总结为一句话是:将类路径下 META-INF/spring.factories 里面配置的所有 EnableAutoConfiguration 的值加入到容器中)
  • 每一个如下这样的 xxxAutoConfiguration 类都是容器中的一个组件,都加入到容器中,用它们来做自动配置。每一个自动配置类进行自动配置功能。
# 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.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
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.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
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.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
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.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
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.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
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.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
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.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
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.ClientHttpConnectorAutoConfiguration,\
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,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
  • HttpEncodingAutoConfiguration 为示例解释自动配置原理
@Configuration(proxyBeanMethods = false) //表示这是一个配置类,和之前的配置文件一样,也可以给容器添加组件
@EnableConfigurationProperties({ServerProperties.class}) //启动指定类的 ConfigurationProperties 功能;将配置文件中对应的值和 ServerProperties 绑定起来,并把  ServerProperties 加入到 ioc 容器中
@ConditionalOnWebApplication(type = Type.SERVLET)  //Spring 底层 @Conditional 注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效。(该注解翻译过来就是:判断当前应用是否是 web 应用,如果是,当前配置类生效)
@ConditionalOnClass({CharacterEncodingFilter.class})  //判断当前项目有没有 CharacterEncodingFilter 这个类;该类是 SpringMVC 中进行乱码解决的过滤器
@ConditionalOnProperty(
    prefix = "server.servlet.encoding",
    value = {"enabled"},
    matchIfMissing = true
)      //判断配置文件中是否存在某个配置:server.servlet.encoding.enabled   如果不存在,判断也成立(意思是:即使我们的配置文件中不配置server.servlet.encoding.enabled=true ,也是默认生效的)
public class HttpEncodingAutoConfiguration {
    private final Encoding properties;     //它已经和 SpringBoot 的配置文件映射了
    //只有一个有参构造器的情况下,参数值就会从容器中获取
    public HttpEncodingAutoConfiguration(ServerProperties properties) {
        this.properties = properties.getServlet().getEncoding();
    }
    @Bean    //给容器中添加一个组件,这个组件的某些值需要从 properties 中获取
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
        return filter;
    }
  • 所有在配置文件中能配置的属性都是在 xxxProperties 类中封装着;配置文件能配置什么就可以参照某个功能对应的这个属性类。一旦这个配置类生效,这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的 properties 类中获取的,这些类里面的每一个属性又是和配置文件绑定的。
@ConfigurationProperties(
    prefix = "server",
    ignoreUnknownFields = true
)     //从配置文件中获取指定的值个 bean 的属性进行绑定
public class ServerProperties {
    private Integer port;
    private InetAddress address;
    @NestedConfigurationProperty
    private final ErrorProperties error = new ErrorProperties();
    private ServerProperties.ForwardHeadersStrategy forwardHeadersStrategy;
    private String serverHeader;
    private DataSize maxHttpHeaderSize = DataSize.ofKilobytes(8L);
    private Shutdown shutdown;
    @NestedConfigurationProperty
    private Ssl ssl;
    @NestedConfigurationProperty
    private final Compression compression;
    @NestedConfigurationProperty
    private final Http2 http2;
    private final ServerProperties.Servlet servlet;
    private final ServerProperties.Tomcat tomcat;
    private final ServerProperties.Jetty jetty;
    private final ServerProperties.Netty netty;
    private final ServerProperties.Undertow undertow;

(2)如何判定配置文件的内容生效

  可以通过启用 debug = true 属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、SpringBoot 整合日志

1、日志框架

(1)市面上的主流日志框架

日志门面(日志的抽象层)日志的实现
JCL(Java Commons Logging) 、SLF4J(Simple Logging Facade for Java)、jboss-loggingLog4j、JUL(java.util.logging)、Log4j2、Logback

(2)日志框架的选择

日志门面:SLF4J
日志实现:Logback

  SpringBoot 底层是 Spring 框架,Spring 框架默认是使用 JCL;而 SpringBoot 选用 SLF4J 和 Logback。

2、Slf4j 的使用

(1)如何在系统中使用 slf4j

  开发的时候,日志记录方法的调用,不应该直接调用日志的实现类,而是调用日志抽象层里面的方法;应该给系统导入 slf4j 的 jar 包和 logback 的实现 jar 包。使用示例如下:

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");
  }
}

  每一个日志的实现框架都有自己的配置文件。使用 slf4j 后,配置文件还是做成日志实现框架自己本身的配置文件。
在这里插入图片描述

(2)解决框架原有日志包的问题

如何将系统中所有的日志都统一到 slf4j :

  • 将系统中其它日志框架先排除出去;
  • 用中间包来替换原有的日志框架;
  • 我们导入 slf4j 其它的实现。
    在这里插入图片描述

3、SpringBoot 日志关系

查看 pom.xml 文件的依赖关系:
在这里插入图片描述
SpringBoot Starter 的依赖关系:

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

在这里插入图片描述
SpringBoot 使用下列依赖来做日志功能:

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

SpringBoot 日志的底层依赖关系:

  • logback-classic和logback-core表示:使用 logback 记录日志
  • jul-to-slf4j 和 log4j-to-slf4j 表示:把其他日志转为 slf4j
  • slf4j-api 表示:导入了日志抽象层 slf4j
    在这里插入图片描述
    移除默认日志依赖:
      Spring 框架用的是 commons-logging,SpringBoot 在其底层将 commons-logging 移除。
      SpringBoot 能自动适配所有的日志,而且底层使用 slf4j + logback 的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架移除掉。
<dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <exclusions>
             <exclusions>
                   <groupId>commons-logging</groupId>
                   <artifactId>commons-logging</artifactId>
             </exclusions>
      </exclusions>
</dependency>

4、SpringBoot 日志的使用

(1)默认配置

SpringBoot 默认配置好了日志,日志的默认级别为 info 。

日志的级别:
   trace < debug < info < warn < error
当日志设置为某一个级别时,只有优先级大于等于设置级别的日志信息会输出

当日志文件超过10Mb之后,会重新创建一个文件来记录日志。

(2)日志的设置


# 指定在某个包下的日志输出级别
logging.level.com.lgk = info


# 会在当前项目跟路径下创建该文件目录,里面的日志记录文件默认为:spring.log
logging.file.path=springboot

# 若是只指定日志输出文件名,则会在当前项目跟路径下创建该文件用于记录日志
# logging.file.name=springboot-test.log

# 如果既指明包名又有 .log 文件,则会在该当前项目跟路径下创建该 .log 文件并将日志记录在里面
# logging.file.name= spring/spring-test.log


#####  在控制台输出的日志格式    #####
## %d:表示时间,后面的是时间的输出格式
## %thread:表示线程名
## %-5level:表示左对齐,并间距5字符
## %logger{50}:表示日志名称,并最长占50个字符,否则按照句点分割
## %msg:表示日志信息
## %n:换行
logging.pattern.console= %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

#####  指定在文件中日志的输出格式    #####
logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n

(3)使用指定的配置文件

  在类路径(resources)下放上每个日志框架自己的配置文件即可。只要放入指定文件,SpringBoot 就不使用默认配置的。

日志实现系统日志文件格式
Logbacklogback.xml 、 logback.groovy 、 logback-{profile}.xml 、 logback-{profile}.groovy
Log4j2log4j2.xml 、 log4j2-{profile}.xml
jul(java util logging)logging.properties

**logback.xml:**这种文件直接就被日志框架识别了。
**logback-{profile}.xml:**这种文件日志框架不直接加载日志的配置项,由SpringBoot 解析日志配置,可以使用 SpringBoot 的高级profile功能实现。

<springProfile name = "dev">
    可以在 application.yml/properties 中使用上 spring.profiles.active = dev 指定配置只在某个环境下生效
</springProfile>

否则,会报如下错误信息:

no applicable action for [springProfile]

5、SpringBoot 切换日志框架

可以按照 slf4j 的日志适配图,进行相关的切换。
slf4j + log4j 的方式:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
        <exclusion>
            <artifactId>log4j-to-slf4j</artifactId>
            <groupId>org.apache.logging.log4j</groupId>
        </exclusion>
    </exclusions>
</dependency>

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

切换为 log4j2:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>spring-boot-starter-logginglog</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>-org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j</artifactId>
</dependency>

四、SpringBoot 开启Web开发

1、使用 SpringBoot 开发步骤

  • 创建 SpringBoot 应用,选中我们需要的模块;
  • SpringBoot 已经默认将这些场景自动配置好了,我们只需要在配置文件中指定少量配置就可以运行起来;
  • 编写业务代码。

2、SpringBoot 对静态资源的映射规则

        protected void addResourceHandlers(ResourceHandlerRegistry registry) {
            super.addResourceHandlers(registry);
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                ServletContext servletContext = this.getServletContext();
                this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (servletContext != null) {
                        registration.addResourceLocations(new Resource[]{new ServletContextResource(servletContext, "/")});
                    }

                });
            }
        }
        
        // 配置欢迎页映射
        @Bean
        public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
            WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
            welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
            welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
            return welcomePageHandlerMapping;
        }
  • 所有 /webjars/** 下的路径访问都去 classpath:/META-INF/resources/webjars/ 找资源
      webjars(https://www.webjars.org):以 jar 包的方式引入静态资源;在访问的时候只需要写 web jars 下面资源的名称即可。例如:http://localhost:8080/webjars/jquery/3.6.0/jquery.js
    在这里插入图片描述
    jquery-webjars 的目录结构:
    在这里插入图片描述
  • / ** 访问当前项目的任何资源(静态资源文件夹)
## java 包和 resources 包都是类路径的根目录
classpath: /META_INF/resources/    (表示可以在java包或resources包下创建)
classpath: /resources/             (表示可以在java包或resources包下创建一个resources目录)
classpath: /static/                (表示可以在java包或resources包下创建一个static目录,原项目创建时已有)
classpath: /public/                (同理,可以在java包或resources包下创建一个public目录)
/ :                                (当前项目的根路径,即项目名之下)

  假设访问:localhost:8080/abc 如果没有被处理,默认去静态资源文件夹里找 abc

  • 欢迎页;静态资源文件夹下的所有 index.html 页面; 被 /** 映射。
      示例:localhost:8080/asserts/js/Chart.min.js(asserts 目录放在静态资源目录 static 下)
  • 所有的“ ** /favicon.ico” 都是在静态资源文件下找。(favicon.ico是浏览器地址栏上的图标)

小知识点:
  可以通过在 application.yml 文件中配置 spring.resource.static-location=classpath:/作为新的静态资源文件夹/,classpath:/作为新的静态资源文件夹/ 的方式改变原有默认的静态资源文件夹路径。

3、模版引擎

  SpringBoot 推荐的模版引擎 Thymeleaf;语法简单,功能相比其它模版引擎更强大。

(1)引入 Thymeleaf

        <!--  引入模版引擎 thymeleaf-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

<!--  	切换 thymeleaf 版本	  -->
<properties>
        <java.version>1.8</java.version>
        <!-- 使用 thymeleaf 3.0.12 版本替换原来版本 -->
        <thymeleaf.version>3.0.12.RELEASE</thymeleaf.version>
        <!--  布局功能的支持程序 thymeleaf3 搭配 layout2 以上版本-->
        <!-- thymeleaf2 搭配 layout1 -->
        <thymeleaf-layout-dialect.verion>2.1.1</thymeleaf-layout-dialect.verion>
</properties>

(2)Thymeleaf 语法与使用

  由默认配置可知,只要我们把 HTML 页面放在 classpath:/templates/ 下,thyme leaf 就能自动渲染。


@ConfigurationProperties(
    prefix = "spring.thymeleaf"
)
public class ThymeleafProperties {
    private static final Charset DEFAULT_ENCODING;
    public static final String DEFAULT_PREFIX = "classpath:/templates/";
    public static final String DEFAULT_SUFFIX = ".html";
    private boolean checkTemplate = true;
    private boolean checkTemplateLocation = true;
    private String prefix = "classpath:/templates/";
    private String suffix = ".html";
    private String mode = "HTML";
    private Charset encoding;
    private boolean cache;
    private Integer templateResolverOrder;
    private String[] viewNames;
    private String[] excludedViewNames;
    private boolean enableSpringElCompiler;
    private boolean renderHiddenMarkersBeforeCheckboxes;
    private boolean enabled;
    private final ThymeleafProperties.Servlet servlet;
    private final ThymeleafProperties.Reactive reactive;

使用 thymeleaf :

  • 导入 thymeleaf 的名称空间:xmlns=“http://www.thymeleaf.org”;作用是有语法提示。
<!DOCTYPE html>
<!-- 导入 thymeleaf 的名称空间 -->
<html lang="en" xmlns="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h1>成功!</h1>
</body>
</html>
  • 使用 thymeleaf 语法
<!DOCTYPE html>
<html lang="en" xmlns="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>成功!</h1>
        <!--  th:text 作用是将 div 文本内容设置为传入的内容  -->
        <!--  注意:不要加 @ResponseBody 注解  -->
        <div th:text="${hello}">原来的内容</div>
    </body>
</html>
  • 语法规则(https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.pdf)
      1:片段包含:jsp:include
      2:遍历
      3:条件判断
      4:声明变量
      5:任意属性修改,支持prepend、append
      6:修改指定属性默认值
      7:修改标签体内容,text 转义特殊字符,utext 不转义特殊字符
      8:声明片段
    在这里插入图片描述
  • 表达式语法
Simple expressions(表达式语法):

    VariableExpressions: ${...} :获取变量值;其实是OGNL
                              特性:
                              (1)获取对象的属性,调用方法
                              (2)使用内置的对象
                                   #ctx : the context object.
                                   #vars: the context variables.
                                   #locale : the context locale.
                                   #request : (only in Web Contexts) the HttpServletRequest object.            
                                   #response : (only in Web Contexts) the HttpServletResponse object. 
                                   #session : (only in Web Contexts) the HttpSession object. 
                                   #servletContext : (only in Web Contexts) the ServletContext object.
                              (3)内置的工具对象
                                   #execInfo : information about the template being processed.
                                   #messages : methods for obtaining externalized messages inside variables expressions, in the same way as they would be obtained using #{...} syntax.
                                   #uris : methods for escaping parts of URLs/URIs
                                   #conversions : methods for executing the configured conversion service (if any).
                                   #dates : methods for java.util.Date objects: formatting, component extraction, etc.
                                   #calendars : analogous to #dates , but for java.util.Calendar objects.
                                   #numbers : methods for formatting numeric objects.
                                   #strings : methods for String objects: contains, startsWith, prepending/appending, etc.
                                   #objects : methods for objects in general.
                                   #bools : methods for boolean evaluation.
                                   #arrays : methods for arrays.
                                   #lists : methods for lists.
                                   #sets : methods for sets.
                                   #maps : methods for maps.
                                   #aggregates : methods for creating aggregates on arrays or collections.
                                   #ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
    
    SelectionVariableExpressions: *{...} :选择表达式;和${}在功能上一样。补充使用:配合 th:object="${}"使用
    
    MessageExpressions: #{...} :获取国际化内容
    
    LinkURLExpressions: @{...} :定义URL
    
    Fragment Expressions: ~{...}:片段引用表达式

Literals(字面量):
    Text literals: 'one text' , 'Another one!' ,... 
    Number literals: 0 , 34 , 3.0 , 12.3 ,... 
    Boolean literals: true , false
    Nullliteral: null
    Literal tokens: one , sometext , main ,... 

Text operations:(文本操作)
    Stringconcatenation: +
    Literal substitutions: |The name is ${name}|

Arithmetic operations: (数学运算)
    Binaryoperators: +, -, *, /, %
    Minussign(unaryoperator): - 

Boolean operations:(布尔运算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not

Comparisons and equality:(比较运算)
    Comparators: >, <, >=, <= (gt, lt, ge, le)
    Equality operators: == , != ( eq , ne ) 

Conditional operators:(条件运算)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else) 
    Default: (value) ?: (defaultvalue)
  • 示例:
 @RequestMapping("/success")
    public String success(Map<String,Object> map){
        map.put("hello","<h1>你好啊</h1>");
        map.put("users", Arrays.asList("aaa","bbb","ccc"));
        return "success";
    }

<!DOCTYPE html>
<html lang="en" xmlns="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>成功!</h1>
        <div th:text="${hello}">原来的内容</div>

        <hr/>
        <div th:text="${hello}">
        </div>
        <div th:utext="${hello}"></div>
    <hr/>
        <h3 th:each="user : ${users}" th:text="${user}"></h3>
        <h3>
            <span  th:each="user : ${users}" >[[${user}]]</span>
        </h3>
    </body>
</html>

在这里插入图片描述

4、Spring Boot 底层对 Spring MVC 的自动配置

Spring Boot 开发文档:https://docs.spring.io/spring-boot/docs/1.5.10.RELEASE/reference/htmlsingle/#boot-features-developing-web-applications

(1)Spring Boot 对 Spring MVC 的默认配置

Spring Boot 自动配置好了 Spring MVC ;以下是Spring Boot 对 Spring MVC 的默认配置:

  • Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
      自动配置了 ViewResolver(视图解析器):根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发或是重定向)
      ContentNegotiatingViewResolver:组合所有的视图解析器
      如何定制自己的:可以自己给容器添加一个视图解析器;Spring Boot 自动将其组合起来
  • Support for serving static resources, including support for WebJars (see below). (静态资源文件夹路径 webjars)
  • Automatic registration of Converter, GenericConverter, Formatter beans.
      自动注册了 Converter, GenericConverter, Formatter beans
      Converyer:转换器;类型转换使用
      Formatter:格式化器;例如转换时间格式
  • Support for HttpMessageConverters (see below).
      HttpMessageConverters:Spring MVC 用来转换Http请求和响应的
      HttpMessageConverters 是从容器中确定;获取所有的 HttpMessageConverter
      自己给容器添加 HttpMessageConverter,只需要将自己的组件注册在容器中(用@Bean 、@Component…)
  • Automatic registration of MessageCodesResolver (see below).(定义错误代码生成规则)
  • Static index.html support. (静态资源首页访问)
  • Custom Favicon support (see below). (浏览器图标 favicon.ico)
  • Automatic use of a ConfigurableWebBindingInitializer bean (see below).
      我们可以配置一个 ConfigurableWebBindingInitializer 来替换默认的添加到容器中

If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

(2)扩展 Spring MVC

编写一个配置类(@Configuration 标注),是 WebMvcConfigurerAdapter 类型,不能标注 @EnableWebMvc

@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
    
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 浏览器发送 /hi 请求来到 success 
        registry.addViewController("/hi").setViewName("success");
    }
}

(2)全面接管 Spring MVC

  Spring Boot 对 Spring MVC 的自动配置不需要了,所有的都是我们自己配置;所有的 Spring MVC 的自动配置都失效了。

我们只需要在配置类中加 @EnableWebMvc 注解即可。

5、如何修改 Spring Boot 底层的默认配置

Spring Boot 的模式:

  • Spring Boot 在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean 、@Component),如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(例如:ViewResolver),则将用户配置和默认配置组合起来。
  • Spring Boot 中会有非常多的 xxxConfigurer 帮助我们扩展配置

6、Spring Boot Web 开发剩余部分后续补充!!!

五、SpringBoot 与Docker

1、Docker 简介

  Docker 是一个基于 Go 语言,并遵从 Apache2.0 协议的开源应用容器引擎;Docker 支持将软件编译成一个镜像,然后在镜像中为这个软件做好配置,将镜像发布出去,其它使用者可以直接使用这个镜像。运行中的这个镜像称为容器,容器启动非常迅速。

2、Docker 的核心概念

  • Docker 主机(host):安装了 Docker 程序的机器(Docker 安装在操作系统之上);
  • Docker 客户端(Client):连接 Docker 主机进行操作;
  • Docker 仓库(Registy):用来保存各种打包好的软件镜像;
  • Docker 镜像(Images):软件打包好的镜像;放在 Docker 仓库中;
  • Docker 容器(Container):镜像启动后的实例称为一个容器;容器是独立的一个或一组应用

使用 Docker 的步骤:
  1)、安装 Docker ;
  2)、去 Docker 仓库找到这个软件对应的镜像;
  3)、使用 Docker 运行这个镜像,这个镜像就会生成一个 Docker 容器;
  对容器的启动停止就是对软件的启动与停止。

3、Linux 环境下安装 Docker

(1)安装 Linux 虚拟机

  • VMWare、Virtual Box(安装这个);
  • 导入虚拟机文件 centos7.ova
  • 双击启动 Linux 虚拟机,使用账户密码登陆
  • 使用客户端连接 Linux 服务器进行命令操作
  • 设置虚拟机网络:桥接网络;选好网卡(有线或无线);接入网络(在高级里勾选)
  • 设置好网络后使用命令(或关闭虚拟机重启)重启虚拟机网络:service network restart
  • 查看 Linux 的 IP 地址:ip addr
  • 使用客户端连接

(2)在 Linux 上安装 Docker

  • 查看 centos版本;Docker 要求 centos 系统的内核版本高于3.10。可以使用 uname -r 查看版本
  • 如果内核版本过低,可以使用: yum update 升级软件包及内核
  • 安装 Docker :yum install docker 即可
  • 启动 Docker :systemctl start docker
  • 查看 Docker 版本号:docker -v
  • 开机自启动 Docker :systemctl enable docker
  • 停止 Docker:systemctl stop docker

(3)常用操作

1)、镜像操作

操作命令示例说明
检索docker search 关键字docker search mysqldocker 会到 docker hub 上检索 关键字 的详细信息
拉取docker pull 镜像名:tagdocker pull mysql:tag 是可选的,tag 表示版本标签,多为软件的版本,默认是 latest
镜像列表docker images查看所有本地镜像
删除镜像docker rmi image_iddocker rmi 016bb6bd994删除指定的本地镜像

Docker 镜像库:https://hub.docker.com

2)、容器操作步骤
软件镜像(相当于软件安装程序)-> 运行镜像 -> 产生一个镜像容器(就是正在运行的软件)

操作命令示例说明
搜索镜像docker search tomcatdocker 会到 docker hub 上检索 关键字 的详细信息
拉取镜像docker pull tomcat:tag 是可选的,tag 表示版本标签,多为软件的版本,默认是 latest
运行镜像docker run --name contain_name -d image_namedocker run --name mytomcat -d tomcat:latestcontainer_name:自定义容器名(别名) -d:后台运行 image_name:指定镜像模版
查看容器docker ps查看正在运行的容器
停止容器docker stop container_id/container_namedocker stop mytomcat停止正在运行的容器
查看所有容器docker ps -a查看所有容器,包括运行和不运行
启动容器docker start container_id/container_namedocker start mytomcat
删除容器docker rm container_iddocker rm 016bb6bd994删除指定的容器
端口映射docker run [–name container_name] -p host_port:contain_port -d image_namedocker run --name my tomcat -p 8080:8080 -d tomcat
查看防火墙的状态service firewalld status
关闭防火墙service firewalld stop
查看容器日志docker logs container_name/container_iddocker logs mytomcat

更多 docker 容器命令查看:https://docs.docker.com/engine/reference/command/commandline/docker/

4、Docker 安装软件(示例:mysql)

  有些镜像使用 docker run 镜像名 启动镜像时会不成功启动,例如mysql镜像启动需要 设置参数(MYSQL_ROOT_PASSWOED、MYSQL_ALLOW_EMPTY_PASSWORD、MYSQL_RANDOM_ROOT_PASSWORD)中的其中一个

正确的启动方式为:
  docker run --name mymysql -e MYSQL_ROOT_PASSWOEG=123456 -d mysql(这个是不映射端口的)
或者:
  docker run -p 3306:3306 --name mymysql -e MYSQL_ROOT_PASSWOEG=123456 -d mysql

六、SpringBoot 之数据访问

1、简介

  对于数据访问层,无论是 SQL 还是 NoSQL,Spring Boot 默认采用整合 Spring Data 的方式进行统一处理,添加大量的自动配置,屏蔽了很多配置;引入各种 xxxTemplate 、xxxRespository 来简化我们对数据访问层的操作;对于我们来说只需要简单的设置即可。

2、整合 JDBC 与数据源

(1)引入 starter

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

(2)数据源的配置

application.yml 中数据源的配置如下:

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/databasename
    driver-class-name: com.mysql.jdbc.Driver

数据源的相关配置都在 DataSourceProperties 里面:
在这里插入图片描述

(3)自动配置原理

org.springframework.boot.autoconfigure.jdbc

  • 根据配置创建数据源,默认使用 Tomcat 连接池;可以使用 spring.datasource.type 指定自定义的数据源类型;
  • Spring Boot 默认可以支持的数据源有:
org.apache.tomcat.jdbc.pool.DataSource;
com.zaxxer.hikari.HikariDataSource;
org.apache.commons.dbcp2.BasicDataSource;
oracle.ucp.jdbc.PoolDataSource;
自定义数据源:
@Configuration(
        proxyBeanMethods = false
    )
    @ConditionalOnMissingBean({DataSource.class})
    @ConditionalOnProperty(
        name = {"spring.datasource.type"}
    )
    static class Generic {
        Generic() {
        }

        @Bean
        DataSource dataSource(DataSourceProperties properties) {
            return properties.initializeDataSourceBuilder().build();
        }
    }
  • DataSourceInitializer:ApplicationListener
    作用:
    1)、runSchemaScripts(); 运行建表语句;
    2)、runDataScripts(); 运行插入数据的 sql 语句。
    默认只需要将文件名命名为:
schem-*.sql 、data-*.sql
默认规则:schema.sql 、schema-all.sql
也可以使用下面方式指定位置:
schema:  (- :表示多个元素,参考前面list)
      - classpath: 自定义文件名1.sql
      - classpath: 自定义文件名2.sql
  • 操作数据库:自动配置了 JdbcTemplate 操作数据库

(4)整合 Druid 并配置数据源监控

1)、引入 Druid 数据源

<!-- 引入数据源 Druid -->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.5</version>
</dependency>

2)、在配置文件中配置

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/databasename
    driver-class-name: com.mysql.jdbc.Driver
    
    # 指定 sql 执行文件位置
#    schema:
#      - classpath: users.sql
    
    # 更换数据源为 druid 
    type: com.alibaba.druid.pool.DruidDataSource
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    # 配置监控统计拦截的 filters,去掉后监控界面 sql 无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: durid.stat.mergeSql=true,druid.stat.slowSqlMillis=500

3)、整合使用数据源 druid

package com.lgk.datasourcejdbc.config;

// 导入数据源
import com.alibaba.druid.pool.DruidDataSource;

import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class DruidConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druid(){
        return new DruidDataSource();
    }

//    配置 Druid 的监控
//    1、配置一个管理后台的 Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
//        initParams.put("allow","localhost");
        initParams.put("allow",""); //默认所有都可以访问
        initParams.put("deny","填写需要填写的IP");
        bean.setInitParameters(initParams);
        return bean;
    }

//    2、配置一个 web 监控的 filter
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

3、整合 MyBatis

Mybatis 中文文档:https://mybatis.org/mybatis-3/zh/index.html

(1)创建

在这里插入图片描述
SpringBoot 整合 MyBatis 相关依赖:

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

(2)注解版 MyBatis

package com.lgk.springbootmybatis.mapper;

import com.lgk.springbootmybatis.bean.Department;
import org.apache.ibatis.annotations.*;

// 指定这是一个操作数据库的 mapper
@Mapper
public interface DepartmentMapper {
    
    @Select("select * from deprtment where id = #{id}")
    public Department getDeptById(Integer id);
    
    @Delete("delete from department where id = #{id}")
    public int deleteDeptById(Integer id);
    
    @Options(useGenerateKeys = true, keyProperty = "id")
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public int insertdDept(Department department);
    
    @Update("update department set departmentName = #{departmentName} where id = #{id}")
    public int updateDept(Department department);
}
  • 使用注解的方式可以在操作数据库接口方法上直接编写 SQL 语句
  • 只需要在操作数据库的 interface 上加 @Mapper 注解,就能使用
  • 当 xxxMapper 特别多的情况下,在每一个 xxxMapper 的接口上都加 @Mapper 注解特别麻烦,可以在 Spring Boot 的主配置类(或者 MyBatis 配置类)上加 @MapperScan(value = “com.lgk.springbootmybatis.mapper”) 注解,相当于在指定包下的接口都加上 @Mapper 注解
  • @Options(useGenerateKeys = true, keyProperty = “id”)表示使用自增ID
  • 自定义驼峰命名规则;在不写配置文件的情况下,给容器中添加一个 ConfigurationCustomizer 即可
package com.lgk.springbootmybatis.config;

import org.apache.ibatis.session.Configuration;
import org.mybatis.spring.boot.autoconfigure.ConfigurationCustomizer;
import org.springframework.context.annotation.Bean;

@org.springframework.context.annotation.Configuration
public class MyBatisConfig {
    
    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return new ConfigurationCustomizer(){
          
            @Override
            public void customize(Configuration configuration){
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
    }
}

(3)配置版 MyBatis

  • 首先在 resources 目录下创建 mybatis/mapper 包
  • 在 mybatis 包下创建一个Mybatis的全局配置文件:mybatis-config.xml
  • 在配置文件中使用驼峰命名规则
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

</configuration>
  • 在 mapper 包下创建 SQL 映射文件: xxxMapper.xml
      namespace ="" 里面是跟接口绑定的全类名:com.lgk.springbootmybatis.mapper.xxxMapper
      resultType = “” 里面的是对应实体类的全类名:com.lgk.springbootmybatis.bean.xxx
      id = “” 里面一般是接口的方法名
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lgk.springbootmybatis.mapper.DepartmentMapper">

    <resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="funkyNumber" property="funkyNumber"/>
        <result column="roundingMode" property="roundingMode"/>
    </resultMap>

    <select id="getUser" resultMap="usermap">
		select * from users
	</select>
    <insert id="insert">
	    insert into users (id, name, funkyNumber, roundingMode) values (
	    	#{id}, #{name}, #{funkyNumber}, #{roundingMode}
	    )
	</insert>

    <resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap2">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="funkyNumber" property="funkyNumber"/>
        <result column="roundingMode" property="roundingMode" typeHandler="org.apache.ibatis.type.EnumTypeHandler"/>
    </resultMap>
    <select id="getUser2" resultMap="usermap2">
		select * from users2
	</select>
    <insert id="insert2">
	    insert into users2 (id, name, funkyNumber, roundingMode) values (
	    	#{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler}
	    )
	</insert>

</mapper>
  • 要让 MyBatis 知道它们的存在,就需要在 application.yml/properties 进行配置
mybatis:
  # 指定 MyBatis 全局配置文件的位置
  config-location: classpath:mybatis/mybatis-config.xml
  # 指定 SQL 映射文件的位置
  mapper-locations: classpath:mybatis/mapper/*.xml

4、整合 SpringData JPA

在这里插入图片描述
如果要更换数据源则可自己更改,建议使用默认

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

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

1)、编写一个实体类(Bean)和数据表进行映射,并且配置好映射关系

package com.lgk.springbootjpa.entity;

import javax.persistence.*;

// 使用 JPA 注解配置映射关系
@Entity  // 告诉 JPA 这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") // 指定来喝和数据库哪张表进行对应;如果省略不写,默认就是表名小写user
public class User {

    @Id //标明这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) //主键的生成策略:自增主键
    private Integer id;
    
    @Column(name = "last_name",length = 50) //标明这是和数据表对应的一个列,长度为50个字符
    private String lastName;
    
    @Column  //省略的情况下默认:列名就是属性名
    private String email;
    

2)、编写一个 DAO 接口来操作实体类对应的数据表(Repository)

  • 继承 JpaRepository<T,ID> 来完成对数据库的操作
  • T 表示的是:实体类名
  • ID 表示的是:该实体表的主键的类型

import com.lgk.springbootjpa.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

// 继承 JpaRepository<T,ID> 来完成对数据库的操作
// 泛型中的 T 表示的是:实体类名 
// ID 表示的是:该实体表的主键的类型
public interface UserRepository extends JpaRepository<User,Integer> {

}

3)、基本配置都在 JpaProperties 中解释(application.yml/properties)

spring:
  datasource:
    url: jdbc:mysql://localhost/databasename
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver

  jpa:
    hibernate:
      # 定义数据表的生成策略:更新或创建数据表结构。当第一次启动没有这个数据表就创建;以后启动有数据表的话就更新
      ddl-auto: update
    # 每次在控制台可以显示 SQL
    show-sql: true
    

七、Spring Boot 原理

(1)创建 SpringApplication

  待后续补!!!

(2)启动应用

  待后续补!!!

(3)事件监听机制

  待后续补!!!

(4)自定义 starter

  待后续补!!!

总结

  待后续补!!!


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值