SpringBoot学习01

一、springBoot-入门

0.学习视频来源与简介

SpringBoot 视频教程全集(112P)| 23 小时从入门到精通:

https://www.bilibili.com/video/av59572480
在这里插入图片描述


0.1.简介

在这里插入图片描述

通过上面的图,我们可以看出,springboot的学习入口非常小,但是想要精通,困难很大,要掌握spring框架以及…

springboot是什么?

简化spring应用开发的一个框架;

整个spring技术栈的一个大整合;

J2EE开发的一站式解决方案;

优点**:

  • 快速创建独立运行的spring项目已经与主流框架继承

  • 使用嵌入式的Servlet容器,应用无需打成WAR包

    • 比如在开发web项目中,想要运行项目,就要将项目打包成war包,放到Tomcat等服务器上运行,现在,不用再打包成war包,而是打包成jar包,就可以使用java的命令运行项目了。
  • starters自动依赖与版本控制

    • 也称为启动器。功能就是自动的导入依赖并且版本控制。

    • 如果我们想要使用某一块的功能,就会有相应的启动器。比如我们想要用jdbc功能,就导入jdbc相关starters,想要用redis功能,就导入redis相关starters。

  • 大量的自动配置,简化开发,也可以修改默认值

    • 我们想要使用的功能、框架,springboot都自动帮我们配置好,我们只需要一个很小的入口,不用再进行一大堆的配置
  • 无需配置XMl,无代码生成,开箱即用

    • springboot内部的API已经帮我们创建好的各种配置的XML,我们只需要直接使用springboot创建项目就好
  • 准生产环境的运行时应用监控

    • 比如运维时的状况等都能够监控到
  • 与云计算的天然集成

缺点:

  • 是基于spring框架的再封装,如果对spring框架不是很了解, 那么对springboot的整个封装机制也不是很了解

视频学习的SpringBoot版本:1.5.9.RELEASE


1.入门

1.环境约束:

  • jdk1.8
  • maven3.x:3.3以上
  • idea 2018
  • springBoot 1.5.9.RELEASE

使用springboot创建一个HelloWorld:

一个功能:浏览器发生hello请求,服务器接收请求并处理,响应Hello World 字符串。

2.导入依赖

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>

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

3.编写一个主程序,用户启动springBoot应用:

package com.wwj;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

/**
 * @SpringBootApplication: 用来标注一个主程序类,说明这时一个springBoot应用
 */
@SpringBootApplication
public class Helloworld {

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

4.编写相关的Controller、Servive:

package com.wwj.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    @RequestMapping("/hello")
    @ResponseBody
    public String hello() {

        return "Hello World!!!";
    }
}

5.运行主程序

在这里插入图片描述

上面运行主程序后就相当于在Tomcat服务器上运行了。

之后在浏览器上访问http://localhost:8080/hello,就能得到返回值Hello World!!!

6.简化部署

要创建可执行文件 jar 文件,要引入下面插件。可以将应用打包成一个可以执行的jar包,之后直接执行该jar包就能运行该应用。

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

引入插件后,运行maven的打包命令mvn package完成打包,就可以在target目录下找到xxx.jar包了。想要运行jar包,打开终端,找到jar包所在的目录,执行命令java -jar就能运行应用了,想要退出应用,点击 ctrl-c 键。

如果要查看jar包内部,可以使用jar tvf命令。

7.1.HelloWorld探究

7.1.pom.xml文件:
1.父项目
HelloWorld项目的父项目为:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>
而spring-boot-starter-parent项目的父项目又为:
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>1.5.9.RELEASE</version>
    <relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他才是真正管理springboot应用里面的所有依赖版本;也称为springboot的版本仲裁中心。

因为仲裁中心已经把springboot的一切相关依赖都版本管理了起来,所以以后我们导入依赖默认是不需要写版本。但是没有在spring-boot-dependencies里面管理的依赖自然需要版本号。

2.导入的依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter-web :分成两部分。

spring-boot-starter:spring-boot场景启动器;

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

7.2.主程序类(入口类)
/**
 * @SpringBootApplication: 用来标注一个主程序类,说明这时一个springBoot应用
 */
@SpringBootApplication
public class Helloworld {

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

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

@SpringBootApplication注解又是什么呢?有什么作用?:

@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的配置类。

  • 在@SpringBootConfiguration注解里面又是引用了@Configuration注解。

  • @Configuration:

    • 配置类上标志这个注解。在使用Spring框架时用该注解来标志配置类。
    • 配置类—配置文件XML;配置类也是容器中的一个组件;@Component

@EnableAutoConfiguration:

  • 作用:开启自动配置功能;

  • 以前我们要使用某个功能,要进行很多的配置,现在,只用该注解,Springboot就会帮我们自动配置;该注解告诉SpringBoot开启自动配置功能;这样自动配置才能生效。

  • 该注解又有什么呢:

  • @AutoConfigurationPackage
    @Import({EnableAutoConfigurationImportSelector.class})
    public @interface EnableAutoConfiguration {...}
    
  • @AutoConfigurationPackage:自动配置包

    • 那是配置什么包?再打开注解,会发现有@Import({Registrar.class})代码。
      • @Impor:Spring底层注解,给容器中导入一个组件;导入的组件由Registrar.class这个类控制。
      • 作用:将主配置类(标志了@SpringBootApplication注解的类)的所在包以及下面所有自爆里面的所有组件扫描到Spring容器中
  • @Import({EnableAutoConfigurationImportSelector.class}):

    • EnableAutoConfigurationImportSelector:导入那些组件的选择器
  • EnableAutoConfigurationImportSelector类的父类的selectImports(AnnotationMetadata)方法将需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;

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

    • 在这里插入图片描述

    • 有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;

    • 那又是如何知道这些要导入的组件的配置类的全类名的?

    • 在EnableAutoConfigurationImportSelector类的父类的selectImports方法中,有一行代码

    List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
    获取候选的配置
    

    在这行代码的getCandidateConfigurations方法中,有一个loadFactoryNames方法:

    List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
    

    在loadFactoryNames方法中,会使用类加载器,加载jar包中已经定义好了的文件,从中获取到自动配置类的全类名。

    classLoader.getResources("META-INF/spring.factories")
    

    J2EE的整体解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar包中。


2.使用Spring Initializr快速创建springBoot项目

在这里插入图片描述

在Artifact中,不能使用大写字母,否则出现Artifact contains illegal characters错误。
在这里插入图片描述

最后创建好后的项目结构:在这里插入图片描述

默认生成的SpringBoot项目:

  • 主程序已经写好了,我们只需要写自定的逻辑就好
  • resources文件夹中的目录结构
    • static:保存所有的静态资源;js/css/img等
    • templates:保存所有的模版页面;(SpringBoot默认打包的jar包使用嵌入式的Tomcat,默认不支持jsp页面);可以使用模版引擎(freemarker/thymeleaf);
    • application.properties:springBoot应用的配置文件;可以修改一些默认的设置;(比如在文件中写入:server.port=8081,则表示启动的Tomcat的端口为8081)


二、配置文件

1.配置文件

SpringBoot使用一个全局的配置文件,配置文件名是固定的(两种文件格式):

*application.properties

*application.yml

配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好了;

配置文件放在src/main/resources目录或类路径/config

properties格式的文件都知道使用,但是.yml格式的文件:.yml是YAML(YAML Ain`t Markup Language)语言的文件,以数据为中心,比json、xml等更适合做配置文件。

全局配置文件可以对一些默认配置值进行修改。

YAML:配置例子

server:
  port: 8081

XML:配置例子

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

2.YAML语法

1.基本语法

K:(空格)V 表示一对键值对(空格必须有);

空格的缩进来控制层级关系;空格的多少无所谓,只要是左对齐的一列数据,都是同一个层级的;大小写敏感

server:
  port:8081
  path:/hello

2.值的写法

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

k: v:字面直接来写;

字符串默认不用加上单引号或者双引号;若加上,则有以下规则:

​ “”:双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表达的意思

​ name: “zhangsan \n lisi”:输出:zhangsan 换行 lisi

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

​ name: “zhangsan \n lisi”:输出:zhangsan \n lisi

2.对象、Map(属性和值)(键值对):

对象还是k: v的方式:

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

server:
 port:8081
 path:/hello

行内写法:

server:{port:8081,path:/hello}
3.数组(List、Set):

- 值表示数组中的一个元素:

pets:
 - cat
 - dog
 - pig

行内写法:

pets:[cat,dog,pig]

3.配置文件值注入组件

一:application.yml配置文件

application.yml配置文件中的值:

person:
  name:zhangsan
  age:18
  sex:男

如何使配置文件中的值注入组件中?

/**
 * 将配置文件中配置的每一属性的值,映射到这个组件中来
 *
 * @ConfigurationProperties: 告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定。
 * prefix = "person":配置文件中那个下面的所有属性进行一一映射
 * 		默认是从全局配置文件中获取
 * <p>
 * 只有这个组件是容器中的组件,才能在容器中提供@ConfigurationProperties功能。
 * 所以组件必须被@Component、@Server等注解标志。
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    public String name;
    public Integer age;
    public String sex;

使用上面代码还是不能够将配置文件中的值给注入到组件中的,idea会提示:Spring Boot Configuration Annotation Processor not found in classpath(在类路径中找不到Spring Boot配置注释处理器),我们还要导入配置文件处理器,以后编写配置就能映射到了,并且有提示。

<!--导入配置文件处理器,配置文件进行绑定就会有提示了-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
</dependency>

导入依赖后就有提示:Re-run Spring Boot Configuration Annotation Processor to update generated metadata(重新运行Spring Boot配置注释处理器以更新生成的元数据 ),重新运行SpringBoot就能生效了

二:application.properties配置文件

和上面的一样只是文件中值的写法不一样了而已。

person.age=10
person.name=张三
person.sex=男

那如何在类中获取到配置文件中的值?可以查看spring 注解第三章节的文章。

1.properties配置文件在idea中可以会乱码

解决方法:

在这里插入图片描述

2.@Value@ConfigurationProperties获取值比较

@Value和@ConfigurationProperties都能从配置文件中获取值。

@ConfigurationProperties@Value
功能批量注入配置文件中的属性值一个个指定
松散绑定(属性名是驼峰式还是中间使用-)支持不支持
spEL不支持支持
JSR303数据校验支持不支持
复杂封装类型支持不支持

在类上标志@Validated注解,表明该类要进行校验。比如在属性上标志@Email注解,表示该属性的值格式是邮件格式。

3.@PropertySource@importResource

@PropertySource:加载指定的配置文件;

因为@ConfigurationProperties注解默认是从全局的配置文件中获取值,若要获取到我们自定义的配置文件,可以使用@PropertySource注解进行指定。如下:

@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    public String name;
    public Integer age;
    public String sex;

@importResource:导入spring的配置文件,让配置文件里面的内容生效;

SpringBoot里面没有spring的配置文件,我们自己编写的配置文件,也不能自动识别;

想让spring的配置文件生效,加载进来;@importResource标志在一个配置类上;

比如一个spring.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">
    
	<!-- com.wwj.helloworldquick.domain.User是一个真实存在的类 -->
    <bean id="user" class="com.wwj.helloworldquick.domain.User"></bean>
</beans>

在应用的开始类上标志上@importResource,并引用spring.xml配置文件;

@ImportResource(value = {"classpath:spring.xml"})
@SpringBootApplication
public class HelloWorldQuickApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloWorldQuickApplication.class, args);
    }
}

测试:

package com.wwj.helloworldquick;
import com.wwj.helloworldquick.controller.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

@RunWith(SpringRunner.class)
@SpringBootTest
class HelloWorldQuickApplicationTests {
    // 获取spring的控制器
    @Autowired
    ApplicationContext ioc;

    @Test
    void t2() {
        boolean user = ioc.containsBean("user");
        System.out.println(user);  // 结果为true
    }
}

但是使用@ImportResource注解有点费劲,spring推荐使用@Configuration注解来标志一个配置类。我们可以新建一个包,来存储应用中用到的配置文件,集中好管理。配置好了配置类后,要使之生效,就要被spring扫描到,但一般来说,在主配置类同级以及之下的包都能被扫描得到。

package com.wwj.helloworldquick.config;

import com.wwj.helloworldquick.domain.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyConfig {
    @Bean
    public User user(){
        System.out.println("---->>>111");
        return new User();
    }
}
// 测试:=---------------
@RunWith(SpringRunner.class)
@SpringBootTest
class HelloWorldQuickApplicationTests {
    // 获取spring的控制器
    @Autowired
    ApplicationContext ioc;

    @Test
    void t2() {
        boolean user = ioc.containsBean("user");
        System.out.println(user);  // 结果为true
    }
}

4.配置文件站位符

1.随机数

r a n d o w . v a l u e 、 {randow.value}、 randow.value{randow.int}、${randow.long}、
r a n d o w . i n t ( 10 ) 、 {randow.int(10)}、 randow.int(10){randow.int[1024,65526]}

2.属性占位符

person.name
person.sex=${app.name}

可以在配置文件中引用在前面配置过的属性(优先级前面配置过的都能生效)

也可以设置默认值,在占位符找不到对应的值时,就使用事先设定好的默认是:${app.name:默认值}


5.环境搭建:Profile

可以参考spring注解篇的4.5章节

1.多Profile文件

我们在主配置问价编写的时候,文件名可以是:

application-{profile}.properties/yml 例子如下:

application-dev.properties

application-prod.properties

默认使用的是application.properties的配置;

2.yml支持多文档方式

server: 
  port: 8081
spring: 
  profiles: dev

# yml文档的使用格式是用三个横线分隔开
---
server: 
  port: 8082
spring: 
  profiles: prod
 

3.激活指定Profile

1.在配置文件中指定:

spring.profiles.active=dev 激活测试环境的配置

spring.profiles.active=prod 激活生产环境的配置

2.命令行方式:

在将项目打包成jar并运行时,启动各种环境。

java -jar hello-world-quick-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev

3.在idea的Edit Configurations…中设置

在idea的Edit Configurations…中-> Program arguments中设置:

–spring.profiles.active=dev

4.设置虚拟机参数

在idea的Edit Configurations…中-> VM options中设置:

-Dspring.profiles.active=dev


6.配置文件加载位置及优先级

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

file:./config/

file:./

其中file是项目所在的目录,也即是config文件夹和src文件夹同级。

classpath:/config/

classpath:/

以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置配置内容会覆盖低优先级配置内容

SpringBoot会从这资格位置加载配置文件;加载的所有配置文件会形成互补配置

1.改变默认的配置文件位置

我们还可以通过"spring.config.location=路径"来改变默认的配置文件位置

spring.config.location=路径不能在配置文件中写,只能在打包的jar包启动项目的时候指定。

项目打包好以后,我们可以使用命令行的方式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用,形参互补配置。


7.外部配置加载顺序

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

  1. 命令行参数

    java -jar hello-world-quick-0.0.1-SNAPSHOT.jar --server.port=8082

    有多个参数,就用空格隔开。

  2. 来自java:comp/env的JNDI属性

  3. java系统属性(System.getProperties)

  4. 操作系统环境变量

  5. RandomValePropertySource配置的random*属性值

    **有jar包外向jar包内进行查找**

    **优先加载带Profile的配置**外部就是和jar包同级。

  6. jar包外部的application-{profile}.properties/yml(带spring.profile)配置文件

  7. jar包内部的application-{profile}.properties/yml(带spring.profile)配置文件
    **再加载不带Profile的配置**

  8. jar包外部的application.properties/yml(不带spring.profile)配置文件

  9. jar包内部的application.properties/yml(不带spring.profile)配置文件

  10. @Configuration注解类上的@PropertySource

  11. 通过SpringApplication.serDefaultProperties指定的默认属性

更多要参数文档,点击这里


8.自动配置的原理

配置文件能写些什么,可以参考SpringBoot的官方文档:点击这里

1.自动配置原理:

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

2)、@EnableAutoConfiguration:

  • 入门部分的7.2章节中,有了一些的自动配置的原理,

  • classLoader.getResources("META-INF/spring.factories")
    主要是扫描所有jar包类路径下的 	META-INF/spring.factories文件
    把扫描到的这些文件的内容包装成properties对象
    从properties中获取到EnableAutoConfiguration.class(类名,也是META-INF/spring.factories文件中的全类名)对应的值,然后把他么添加到容器中
    

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

# 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,\
.......

每一个这样的 xxxxAutoConfiguration 类都是容器中的一个组件,都加入到容器中;作用就是用他们来做配置类

3)、下面以HttpEncodingAutoConfiguration配置类为例:

// 表示这时一个配置类
@Configuration(
    proxyBeanMethods = false
)
// 启动指定类的ConfigurationProperties功能;将配置文件爱你中对应的值和HttpProperties绑定起来;并将HttpProperties加入到容器中。在下面有HttpProperties说明....
@EnableConfigurationProperties({HttpProperties.class})
// SpringBoot底层@Condition注解,根据不同的条件判断使用要加载HttpEncodingAutoConfiguration配置类。如果满足指定的条件,则整个配置类里面的配置就会生效;	这里是判断当前应用是否是web应用,如果是,当前配置类生效;
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
// 判断当前项目有没有这个类;CharacterEncodingFilter类值Springmvc中进行乱码解决的过滤器
@ConditionalOnClass({CharacterEncodingFilter.class})
// 判断配置文件中是否存在某个配置;这里是判断配置文件中是否有spring.http.encoding.enabled;如果不存在,判断也是成立因为matchIfMissing = true;
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {"enabled"},
    matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {

所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;配置文件能配置什么就可以参数某个功能对应的这个属性类了;

@ConfigurationProperties(
    prefix = "spring.http"
)
public class HttpProperties {

例如在配置文件中配置Springmvc的乱码过滤器的编码格式:

spring.http.encoding.charset=utf-8

我们为什么能知道在配置文件中设置上面的值,就是设置了Springmvc的乱码过滤器的编码格式呢,主要是从HttpProperties类中得知的。

所以,我们要修改SpringBoot的默认配置,可以先找到对应场景的自动配置类,再找到自动配置类的属性类(场景的xxxxProperties类中封装着),最后根据@ConfigurationProperties注解的提示并且结合属性类的属性进行设置。


2.@Condition注解的派生类

作用:必须是@Condition注解指定的条件成立,才给容器添加组件,配置类里面的所有内容才能生效。

在这里插入图片描述

3.如何知道那些自动配置类生效

自动配置类必须在一定的条件下才能生效;

那我们怎么知道那些自动配置类已经生效了呢?

我们可以通过在配置文件中加上一条键值对:debug=true;来让控制台打印自动配置报告,这样我们就很方便的知道那些自动配置类生效了。



三、日志

1.日志框架

市面上的日志框架:

JUL/JCL/Jboss-logging/logback/log4j/log4j2/slf4j…

日志门面(日志的抽象层)日志实现
JCL(Jakarta Commons Logging) SLF4j(Simple Logging Facade for java) jboss-loggingLog4j JUL Log4j2 Logback

左边选一个门面(抽象层)、右边选一个实现:

左边: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;

  1. 将系统中其他日志框架先排除出去;
  2. 用中间包来替换原有的日志框架;
  3. 我们导入slf4j其他的实现;

3.SpringBoot日志关系

在这里插入图片描述

总结:

1)、SpringBoot底层也是使用slf4j+logback的方式进行日志记录

2)、SpringBoot也把其他的日志都替换成了slf4j;

3)、中间替换包在这里插入图片描述

4)、如果我们要引入其他框架?一定要把这个框架的默认日志依赖移除掉?是的。

​ SpringBoot框架使用的是Commons-Logging;但是也是排除掉了日志依赖。。。

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.7.0</version>
    <scope>compile</scope>
    <exclusions>
        <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
        </exclusion>
    </exclusions>
    <optional>true</optional>
</dependency>

一句话,SpringBoot能自动失陪所有的日志,而且底层使用slf4j+logback的方式记录日之后,引入其他框架的时候,只需要把这个框架依赖的乳汁框架排除掉。


4.使用日志

1.默认配置

package com.wwj.helloworldquick.controller;
public class Person {
    Logger logger = LoggerFactory.getLogger(getClass());
    public Person() {
        //日志级别:
        // 由高到低:trace< debug< info< warn< error
        // 可以调整日志的输出级别;日志就只会在这个级别以及更高级别生效
        logger.trace("这时trace级别");
        logger.debug("这时debug级别");
        // SpringBoot默认给我们使用的是info级别;
        // 我们可以在配置文件中调整日志的级别:可以只针对某个包或是某个类。
        // 当我们没有给某个包或类指定级别时,就使用springBoot默认的级别:root级别:info级别
        logger.info("这时info级别");
        logger.warn("这是warn级别");
        logger.error("这时error级别");
    }
}

上面代码,若在没有指定级别时,控制台只会输出info级别以及大于info级别的三条日志。

现在,我们在配置文件中设置Person.java类所在的包的日志级别都为trace级别:

logging.level.com.wwj.helloworldquick.controller=trace

这是就能在控制台中输出代码中的五条日志记录了。

2.设置日志级别

所有受支持的 logging 系统都可以使用logging.level.* =日志级别在spring环境配置文件中设置日志级别。

其中日志级别可以为TRACE,DEBUG,INFO,WARN,ERROR,FATAL,OFF 之一。

当然,我们也是可以设置SpringBoot的默认日志级别的:logging.level.root=日志级别

而对于logging.level.* =日志级别的详细用法:

1)、可以设置应用的某个包都使用统一级别:

​ 像是上一个小结(1.默认配置)那样,设置Person.java类所在的包的日志级别都为trace级别:

logging.level.com.wwj.helloworldquick.controller=trace

这样,所有在com.wwj.helloworldquick.controller包下的类的日志级别都似乎trace级别了。

2)、还可以设置某个类单独的日志级别:

logging.level.com.wwj.helloworldquick.controller.Person=trace

3.日志输入到文件

在这里插入图片描述

在这里插入图片描述

在把日志输出到文件中,当文件的容量达到10M时,就会自动的新建一个文件,文件名使用递增的方式命名。


4.日志输出格式

主要使用到的是控制台和文件的输出格式:

logging.pattern.console=%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow} %clr(%5p) [%t] - %clr([ %F ]){yellow} ->>> %m%n
logging.pattern.file=...

在SpringBoot中,我们还可以设置在控制台的输出信息的颜色,方便我们查看日志。

使用方法

像上面的日志输出格式中的那样, 使用%clr转换字配置颜色编码 。

%clr(这里写上想要输出的日志格式){这里写上颜色}

若是不再%clr(...)之后添加大括号设置颜色,则SpringBoot会默认的设置;如日志级别的信息%clr(%5p)就是交给SpringBoot来判断应该使用什么颜色。

支持以下颜色和样式:

  • blue
  • cyan
  • faint
  • green
  • magenta
  • red
  • yellow

5.自定义日志及日志扩展

在这里插入图片描述


四、WEB开发

1.SpringBoot对静态资源的映射规则

@ConfigurationProperties(prefix = "spring.resources",
    ignoreUnknownFields = false)
public class ResourceProperties {
    private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
    // 可以设置和静态资源有关的参数,缓存时间等。。。。
// WebMvcAutoConfiguration.java
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
    } else {
        Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
        CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
        // 说明:当访问项目的路径为"/webjars/**"时,执行该判断,并映射到项目本地的对应的路径
        if (!registry.hasMappingForPattern("/webjars/**")) {
            this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
		
        // 说明:当访问路径不是"/webjars/**"时,而是"/**"时,执行该判断,并映射到应用的响应路径:下面的第二点。
        String staticPathPattern = this.mvcProperties.getStaticPathPattern();
        if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
        }
    }
}

1)、所有/webjars/**下访问路径,都去classpath:/META-INF/resources/webjars/找资源。

​ webjars:以jar包的方式引入静态资源。https://www.webjars.org/

​ 在官网中下载静态资源的maven依赖导入项目中,即可以下面路径找到资源:

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>jquery</artifactId>
    <version>3.3.1</version>
</dependency>

[

运行应用,访问路径:http://localhost:8080/webjars/jquery/3.3.1/jquery.js即可得到对应的静态资源。

2)、"/**" 访问当前项目的任何资源(静态资源的文件夹),会映射到下面的项目文件夹中查找资源。

“/”:当前项目的根路径

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

[

3)、自定义静态资源文件夹

我们可以在配置文件中这样定义我们想要的静态资源文件夹:

spring.mvc.static-path-pattern=/resources/**,classpath:/hello/,classpath:/wwj/

像上面一样就可以定义我们的静态资源文件夹了,而且会把SpringBoot默认的静态资源文件夹给覆盖掉使其不起作用。


1.欢迎页

// WebMvcAutoConfiguration.java
@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));
    return welcomePageHandlerMapping;
}

private Optional<Resource> getWelcomePage() {
    // locations="classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"
    String[] locations = WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations());
    return Arrays.stream(locations).map(this::getIndexHtml).filter(this::isReadable).findFirst();
}

private Resource getIndexHtml(String location) {
    return this.resourceLoader.getResource(location + "index.html");
}

会从locations目录下查找index.html文件,作为欢迎页;

2.自定义图标

Spring Boot 在配置的静态内容位置和 classpath 的根(在该 order 中)中查找favicon.ico。如果存在此类文件,则会自动将其用作 应用的 favicon。

只在静态内容位置查找,不会再进行下一级的查找了


2.引入 templates 模版引擎

市面上的模版引擎

SpringBoot推荐使用的是thymeleaf引擎;语法简单,功能强大

模版引擎的工作原理图:

在这里插入图片描述

1.引入thymeleaf依赖

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

如果想使用thymeleaf 版本2,可以使用下面的方式设置:

<properties>
    <thymeleaf.version>3.0.2.RELEASE</thymeleaf.version>
    布局功能的支持程序,thymeleaf版本3主程序,布局功能要版本2以上。
    <thymeleaf-layout-dialect.version>2.1.1</thymeleaf-layout-dialect.version>
</properties>
更多的对应支持,可以在github官网里面查找。

2.thymeleaf使用

在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";

可以看到,在这里就是类似使用springmvc时的视图解析器功能了,默认配置的前缀是"classpath:/templates/",后缀是".html";

3.thymeleaf语法

可以查看Thymeleaf 教程

也可以看文章:17-thymeleaf–>thymeleaf01-入门.md


3.springmvc自动配置

1.Spring MVC auto-configuration

SpringBoot自动配置好了springMVC;一下是SpringBoot对springmvc的默认配置:

  • 包含ContentNegotiatingViewResolverBeanNameViewResolver beans。

    • 自动配置了ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(装发?重定向?))
    • ContentNegotiatingViewResolver:组合所有的视图解析器的;
    • 如果定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合进来;
  • 支持提供静态资源,包括对 WebJars 的支持

    • 静态资源文件夹路径、webjars
  • 自动注册ConverterGenericConverterFormatter beans。

    • Converter:转换器;类型转换就使用Converter;

    • Formatter:格式化器;2020/03/13===Date;

    • @Bean
      @ConditionalOnProperty(    
          prefix = "spring.mvc",    name = {"date-format"})
      public Formatter<Date> dateFormatter() {
          return new DateFormatter(this.mvcProperties.getDateFormat());
      }
      

      添加自己的格式化转换器,我们只需要放在容器中即可。

  • 支持HttpMessageConverters

    • springmvc用来转换Http请求和响应的;User–json;
    • HttpMessageConverters:是从容器中确定;获取所有的HttpMessageConverter;
    • 若想自己添加HttpMessageConverter,只要将自己的组件添加到容器中即可。
  • 自动注册MessageCodesResolver

    • 定义错误代码生成规则
  • 静态index.html支持。

    • 静态首页访问
  • 自定义Favicon支持

    • favicon.ico图片
  • 自动使用ConfigurableWebBindingInitializer bean

    • 我们可以配置一个ConfigurableWebBindingInitializer来替换默认的;只要添加到容器中即可;

    • 初始化 WebDataBinder

      请求数据=====javaBean

2.扩展springmvc

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 .


如果你想保留 Spring Boot MVC features,你只想添加额外的MVC configuration(拦截器,格式化器,视图控制器 etc.),你可以添加自己的@Configuration class 类型为WebMvcConfigurerAdapter,但没有 @EnableWebMvc注解。如果你想提供RequestMappingHandlerMappingRequestMappingHandlerAdapterExceptionHandlerExceptionResolver的自定义实例可以声明提供此类组件的WebMvcRegistrationsAdapter实例。

如果要完全控制 Spring MVC,可以添加自己的@Configuration注释和@EnableWebMvc

扩展:即保留了所有的自动配置,也能用我们扩展的配置;

package com.wwj.helloworldquick.config;
// ...
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {

    // 扩展视图解析器
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        // 浏览器发送 /hello2 请求,会跳转到名为 hello 的视图;
        registry.addViewController("/hello2").setViewName("hello");
    }
    // ..... 
}

原理:
在这里插入图片描述

​ 4)、我们的配置也会被调用:

效果:SpringBoot的自动配置和我们扩展的配置一起作用;

3.全面接管SpringMVc

不要SpringBoot对springmvc的自动配置,所有的配置都是我们自己配置;所有的springmvc的自动配置都失效;

做法:我们需要在配置类中添加注解:@EnableWebMvc

为什么添加了@EnableWebMvc注解,自动配置就失效了:

原理:
在这里插入图片描述

5)、导入的WebMvcConfigurationSupport只是springmvc最基本的功能;


4.如何修改SpringBoot的默认配置

模式:

1)、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean,@Component),如果有就使用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;

2)、在SpringBoot中会有非常多的xxxConfigurer帮组我们进行扩展配置;要多留心;


5.使用小技巧

1)、国际化

详细看SpringBoot09-国际化.md

2)、拦截器

详细看:SpringBoot11-Springboot实现拦截器的两种方式.md

3)、错误处理机制(页面)

1.SpringBoot默认的错误处理机制

默认的返回错误页面效果:在这里插入图片描述

如果是其他客户端(非浏览器),默认相应一个json数据:
在这里插入图片描述

如何判读是浏览器还是非浏览器:

主要是根据请求头的accept属性来判断的,在浏览器中,accept属性有text/html等,在非浏览器中,就是accept:"*/*";

原理:

​ 可以参照ErrorMvcAutoConfiguration类;错误处理的自动配置;

​ 给容器中添加如下组件:

  1. DefaultErrorAttributes:帮我们在页面共享信息

  2. BasicErrorController:处理默认的/error请求

  3. ErrorPageCustomizer:

    @Value("${error.path:/error}")
    private String path = "/error"; // 系统出现错误以后来到error请求进行处理;相当于在web.xml文件中定义的错误页面;
    
  4. DefaultErrorViewResolver:

步骤:

​ 一旦系统出现4xx或5xx之类的错误,ErrorPageCustomizer就会生效(定制错误的响应规则);就会来到/errir请求;就会被BasicErrorController处理;在BasicErrorController处理类中,会有两种处理方法,一种是产生HTML页面(去那个页面是由DefaultErrorViewResolver类处理的),一种是产生json数据;

2.定制错误响应

点击这里:Springboot错误页面和错误信息定制

  1. 如何定制错误的页面

1)、有模版引擎的情况下;error/状态吗;【将错误夜明名为 错误状态码.html 放在模版引擎文件夹里面的error文件夹下】,发生此状态码的错误就会来到对应的页面;

我们还可以使用4xx.html和5xx.html作为错误页面的文件名来匹配这种类型的所有错误,而且会精确查找:有4xx.html和400.html页面,当发生400错误时返回400.html;

DefaultErrorAttributes帮我们在页面共享信息,有:

​ timestamp:时间戳

​ status:砖头码

​ error:错误提示

​ exception:异常对象

​ message:异常信息

​ error:JSR303数据校验的错误都在这里

2)、没有引擎的情况下(模版引起找不到这个错误页面),在静态资源文件夹下找;

3)、以上都没有错误页面,就是SpringBoot默认的错误提示页面

  1. 如何定制错误的json数据

1)、自定义异常处理&返回定制json数据;

@ControllerAdvice
public class MyExceptionHandle {
    @ResponseBody
    @ExceptionHandler(UserNotException.class)
    public Map<String, Object> handleException(Exception e) {
        Map<String, Object> map = new HashMap<>();
        map.put("code", "用户没有登录");
        map.put("message", e.getMessage());
        return map;
    }
}
// 缺点:没有自适应效果。。。。:浏览器和客户端返回的都是json数据

2)、转发到/error进行自适应响应效果处理

@ControllerAdvice
public class MyExceptionHandle {
    @ExceptionHandler(UserNotException.class)
    public String  handleException(Exception e, HttpServletRequest request) {
        Map<String, Object> map = new HashMap<>();
        // 传入我们自己的错误状态码 4xx 5xx 之类的
        request.setAttribute("javax.servlet.error.status_code", 400);
        map.put("code", "用户没有登录");
        map.put("message", e.getMessage());
        // 转发到 /error
        return "forward:/error";
    }
}
// 我们定制的message、code都没有显示出去

3)、将我们的定制数据携带出去;

在第二步的修改中,我们定制的message、code都没有显示出去。

点击这里:Springboot错误页面和错误信息定制


6.嵌入式Servlet容器配置修改

SpringBoot默认使用的是嵌入式的Servlet容器(Tomcat);

1.修改Tomcat的默认规则

略。。。查百度:点击这里

2.注册Servlet三大组件(Serevlet、Fileter、Listener)

由于SpringBoot默认是以jaar包的方式启动嵌入式的Servlet容器来启动SpringBoot的web应用,没有web.xml文件;

所以要注册三大组件,用以下方式:

ServletRegistrationBean

ServletListenerRegistrationBean

FilterRegistrationBean

用法如下:

ServletRegistrationBean

public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doGet(req, resp);
    }
}

@Configuration
public class MyServlet {
    @Bean
    public ServletRegistrationBean servletRegistrationBean(){
        ServletRegistrationBean servlet =  new ServletRegistrationBean();
        servlet.setServlet(new com.wwj.helloworldquick.servlet.MyServlet());
        servlet.addUrlMappings("/myServlet");
        // 也可以使用构造方法:ServletRegistrationBean(Servlet servlet, String... urlMappings)
        return servlet;
    }
}

FilterRegistrationBean:

public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        filterChain.doFilter(servletRequest, servletResponse);
    }
    @Override
    public void destroy() {

    }
}

@Configuration
public class MyServletConfig {
    @Bean
    public FilterRegistrationBean filterRegistrationBean() {
        FilterRegistrationBean filter = new FilterRegistrationBean();
        filter.setFilter(new MyFilter());
        filter.addUrlPatterns("/myFilter");
        return filter;
    }
}

ServletListenerRegistrationBean:

public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("contextInitialized....服务器开启了");
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {
        System.out.println("contextDestroyed....服务器关闭了");
    }
}

@Configuration
public class MyServletConfig {
    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean() {
        return new ServletListenerRegistrationBean(new MyListener());
    }
}

能够监听的类型:

static {
    Set<Class<?>> types = new HashSet();
    types.add(ServletContextAttributeListener.class);
    types.add(ServletRequestListener.class);
    types.add(ServletRequestAttributeListener.class);
    types.add(HttpSessionAttributeListener.class);
    types.add(HttpSessionListener.class);
    types.add(ServletContextListener.class);
    SUPPORTED_TYPES = Collections.unmodifiableSet(types);
}

3.使用其他Servlet容器

Jetty(部分特性:多人对话时的长连接(百度长连接))

Undertow(部分特性:不支持JSP)

         <dependency>
 2             <groupId>org.springframework.boot</groupId>
 3             <artifactId>spring-boot-starter-web</artifactId>
 4             <!--在Web模块中排除默认的Tomcat-->
 5             <exclusions>
 6                 <exclusion>
 7                     <groupId>org.springframework.boot</groupId>
 8                     <artifactId>spring-boot-starter-tomcat</artifactId>
 9                 </exclusion>
10             </exclusions>
11         </dependency>
12 
13         <!--引入其他的servlet容器-->
14         <dependency>
15             <groupId>org.springframework.boot</groupId>
16             <artifactId>spring-boot-starter-jetty</artifactId>
17         </dependency>

其他Servlet容器的使用方法和Tomcat的一样。


4.嵌入式Servlet容器自动配置原理

EmbeddedServletContainerAutoConfiguration(嵌入式Servlet容器自动配置类):


@AutoConfigureOrder(-2147483648)
@Configuration
@ConditionalOnWebApplication
@Import({EmbeddedServletContainerAutoConfiguration.BeanPostProcessorsRegistrar.class})
public class EmbeddedServletContainerAutoConfiguration {
    //....

    @Configuration
    // 判断是否有Tomcat依赖
    @ConditionalOnClass({Servlet.class, Tomcat.class})
    // 判断当前容器没有用户自己定义的EmbeddedServletContainerFactory:嵌入式的Servlet容器工程(作用:创建嵌入式Servlet容器)
    @ConditionalOnMissingBean(
        value = {EmbeddedServletContainerFactory.class},
        search = SearchStrategy.CURRENT
    )
    public static class EmbeddedTomcat {
        public EmbeddedTomcat() {
        }

        @Bean
        public TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory() {
            return new TomcatEmbeddedServletContainerFactory();
        }
    }
}

// 还有很多。。。。。

5.嵌入式Servlet容器启动原理

略。。。


7.使用外置的Servlet容器

嵌入式Servlet容器:应用打成可以执行的jar

​ 优点:简单、便携;

​ 缺点:默认不支持jsp、优化定制想要的功能比较复杂

外置的Servlet容器:外面安装Tomcat(或其他的Servlet容器)-----应用war包的方式打包

使用方法和以前的ssm整合方式一样,不过是使用的SpringBoot的框架。

点击这里


原理:

在这里插入图片描述

步骤:[



五、Docker

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。


Docker是一个开源的应用容器引擎,基于Go语言并遵从Apache2.0协议开源。Docker可以让开发者打包他们的应用以及依赖包到一个轻量级、可以移植的容器中,容器是可以完全使用沙箱机制,相互之间不会有任何接口,更重要的是容器性能开销极低。

Docker支持将软件编译成一个镜像;然后在镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像。运行中的这个镜像称为容器,容器启动是飞车挂快速的。类似Windows里面的ghost操作系统,安装好后什么都有了。


六、数据访问

技术点:JDBC、MyBatis、Spring DataJPA。

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

1.整合基本JDBC与数据源

引入依赖:

<!--引入基础的JDBC-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!--数据库驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.15</version>
</dependency>

连接数据库:

spring:
  datasource:
    url: jdbc:mysql:///my_test?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: 123456
    # 定制数据源的类型。
    type: org.apache.tomcat.jdbc.pool.DataSource

效果:

​ 默认使用org.apache.tomcat.jdbc.pool.DataSource作为数据源;

​ 数据源的相关配置都在DataSourceProperties配置类里面;

可以直接使用org.springframework.jdbc.core.JdbcTemplate操作数据库;

// 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class Springboot03jdbcApplicationTests {
    @Autowired
    DataSource dataSource;

    @Autowired
    JdbcTemplate jdbcTemplate;

    @Test
    public void t1() throws SQLException {
        System.out.println("---------->>>.");
        System.out.println(dataSource);// 判断数据源的连接池类型
        System.out.println(dataSource.getConnection());
        System.out.println("---------->>>.");
        String sql = "select  * from shiro_user";
        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
        System.out.println(maps);
    }
}

2.数据源的高级使用

SpringBoot整合Druid数据源。

Druid是什么?点击这里–Druid中文文档


3.整合MyBatis

更多的详细介绍,观看SpringBoot集成mybatis这篇文章。


定制更多的MyBatis的各种设置:

@org.springframework.context.annotation.Configuration
public class MyBatisConfig {
    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return new ConfigurationCustomizer() {
            @Override
            public void customize(Configuration configuration) {
                //  配置允许驼峰命名法
                configuration.setMapUnderscoreToCamelCase(true);
                //  .....
            }
        };
    }
}

七、自定义starters

Spring Boot入门教程(三十一): 自定义Starter

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值