我是靠谱客的博主 霸气乐曲,最近开发中收集的这篇文章主要介绍SpringBoot介绍SpringBoot目录 SpringBoot介绍_Spring缺点分析 SpringBoot介绍_什么是SpringBoot SpringBoot介绍_SpringBoot核心功能 SpringBoot入门_通过官网搭建项目 SpringBoot入门_通过IDEA脚手架搭建项目 SpringBoot入门_SpringBoot项目结构SpringBoot入门_通过Maven搭建项目 SpringBoot入门_编写Java代码 SpringBoot原理分析_起步依赖Spri,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

目录

SpringBoot目录

 SpringBoot介绍_Spring缺点分析

 SpringBoot介绍_什么是SpringBoot

 SpringBoot介绍_SpringBoot核心功能

 SpringBoot入门_通过官网搭建项目

 SpringBoot入门_通过IDEA脚手架搭建项目

 SpringBoot入门_SpringBoot项目结构

SpringBoot入门_通过Maven搭建项目

 SpringBoot入门_编写Java代码

 SpringBoot原理分析_起步依赖

 查看spring-boot-starter-parent起步依赖

 查看spring-boot-starter-web起步依赖

SpringBoot原理分析_自动配置

 查看注解 @SpringBootApplication 的源码 

查看注解 @EnableAutoConfifiguration 的源码 

 查看AutoConfifigurationImportSelector源码 

 我们 ServletWebServerFactoryAutoConfifiguration 为例来分析源码:

进入 ServerProperties 类源码如下:

 SpringBoot原理分析_核心注解

YAML文件_配置文件介绍 

YAML文件_自定义配置简单数据

 YAML文件_自定义配置对象数据

 YAML文件_自定义配置集合数据

 YAML文件_读取配置文件的数据

使用@Value读取

 使用@ConfigurationProperties读取

YAML文件_占位符的使用

YAML文件_配置文件存放位置及优先级

 YAML文件_bootstrap配置文件

SpringBoot注册web组件_注册Servlet 

SpringBoot注册web组件_注册Filter

SpringBoot注册web组件_注册Listener

SpringBoot访问静态资源_静态资源相关目录

static目录 

 目录结构

 templates目录

SpringBoot访问静态资源_静态资源其他存放位置 

 SpringBoot整合JSP

 Thymeleaf_Thymeleaf入门

 Thymeleaf_变量输出

Thymeleaf_操作字符串

Thymeleaf_操作时间

Thymeleaf_条件判断

 Thymeleaf_迭代遍历

 遍历集合

使用状态变量

遍历Map

 Thymeleaf_获取域中的数据

Thymeleaf_URL写法

在RESTful风格路径中添加参数

Thymeleaf_相关配置

SpringBoot热部署

 SpringBoot整合MyBatis

 SpringBoot参数校验_简单数据类型

 SpringBoot参数校验_异常处理

SpringBoot参数校验_校验相关注解

 SpringBoot参数校验_对象类型

SpringBoot指标监控_添加Actuator功能

 SpringBoot指标监控_Spring Boot Admin

 SpringBoot日志管理

 SpringBoot项目部署_项目打包

 SpringBoot项目部署_多环境配置

 SpringBoot容器化部署_安装Docker环境

SpringBoot容器化部署_Dockerfile制作镜像

SpringBoot容器化部署_Maven插件制作镜像 

 Spring Task_定时任务

Spring Task_入门案例 

 Spring Task_Cron表达式

 Spring Task_Cron实战案例

 Spring Task_@Scheduled

Spring Task_多线程任务


SpringBoot目录

 SpringBoot介绍_Spring缺点分析

 Spring是一个非常优秀的轻量级框架,以IOC(控制反转)和AOP(面向切面)为思想内核,极大简化了JAVA企业级项目的开发。虽然Spring的组件代码是轻量级的,但它的配置却是重量级的。使用Spring进行项目开发需要在配置文件中写很多代码,所有这些配置都代表了开发时的损耗。

 除此之外,Spring项目的依赖管理也是一件耗时耗力的事情。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严重阻碍项目的开发进度。比如Spring5.0以上只能使用Junit4.12以上的版本。

 

 总结
Spring的缺点:

1.配置过于繁琐。
2.引入的依赖过多,版本控制复杂。

 SpringBoot介绍_什么是SpringBoot

SpringBoot对Spring的缺点进行改善和优化,基于约定大于配置的思想,简化了Spring的开发,所谓简化是指简化了Spring中大量的配置文件和繁琐的依赖引入。所以SpringBoot是一个服务于框架的框架,它不是对Spring功能的增强,而是提供了一种快速使用Spring框架的方式。

SpringBoot的优点:
配置简单

1.依赖引入简单
2.提供了一些大型项目的非功能特性,如嵌入式服务器,安全指标,健康监测等。

 SpringBoot介绍_SpringBoot核心功能

 自动配置
     SpringBoot项目自动提供最优配置,同时可以修改默认值满足特定的要求。
起步依赖
SpringBoot的依赖是基于功能的,而不是普通项目的依赖是基于JAR包的。SpringBoot将完成一个功能所需要的所有坐标打包到一起,并完成了版本适配,我们在使用某功能时只需要引入一个依赖即可。

 SpringBoot入门_通过官网搭建项目

接下来我们搭建一个SpringBoot项目,并引入SpringMVC的功能,
首先我们可以通过官网搭建项目:

1.访问start.spring.io
2.生成SpringBoot项目

 

 SpringBoot版本说明:
           SNAPSHOT:快照版,表示开发版本,随时可能修改;
           M1(Mn):M1是milestone的缩写,也就是里程碑版本;

           RC1(RCn):RC1是release candidates的缩写,也就是发布预览版;
           Release:正式版,也可能没有任何后缀也表示正式版

 SpringBoot打包类型说明:
       使用SpringMVC开发的是一个web项目,但由于在SpringBoot中直接嵌入了Tomcat等
       Web容器,所以在使用SpringBoot做Web开发时不需要部署War文件,只需要打成Jar
       包即可。

 SpringBoot入门_通过IDEA脚手架搭建项目

 我们也可以在IDEA中利用脚手架工具搭建项目: 
在IDEA中新建项目,项目类型为Spring Initializr,选择JDK版本
和搭建网站后点击下一步。

 

 脚手架工具也会访问SpringBoot官网进行项目搭建,但SpringBoot官网有时访问速度较慢,我们也可以选择国内的镜像网站https://start.aliyun.com/搭建项目,阿里的脚手架镜像SpringBoot版本有些滞后。

 选择项目参数后,点击下一步

 

 选择SpringBoot版本和需要的起步依赖,点击下一步。

 SpringBoot入门_SpringBoot项目结构

 接下来我们分析SpringBoot的项目结构:

POM文件

SpringBoot项目必须继承spring-boot-starter-parent,即所有的SpringBoot项目都是spring-boot-starter-parent的子项目。
spring-boot-starter-parent中定义了常用配置、依赖、插件等信息,供SpringBoot项目继承使用。

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.7.0-M1</version>
     <relativePath/> 
<!-- lookup parentfrom repository -->
</parent>

SpringBoot项目中可以定义起步依赖,起步依赖不是以jar包为单位,而是以功能为单位

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

spring-boot-maven-plugin插件是将项目打包成jar包的插件。
该插件打包后的SpringBoot项目无需依赖web容器,可以直接使用JDK运行

<build>
  <plugins>
    <plugin>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

启动类
启动类的作用是启动SpringBoot项目,运行启动类的main方法即可
启动SpringBoot项目。

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

配置文件

 由于SpringBoot极大简化了Spring配置,所以只有一个application.properties配置文件,且Spring的自动配置功能使得大部分的配置都有默认配置,该文件的功能是覆盖默认配置信息,该文件不写任何信息都可以启动项目。
启动后默认端口号为8080,我们可以覆盖该配置:

server.port=8888 

SpringBoot入门_通过Maven搭建项目

了解了SpringBoot结构后,我们也可以使用Maven手动搭建
SpringBoot项目:

使用Maven创建普通JAVA项目

 

 

 在pom中添加项目的父工程、起步依赖、插件

<!-- 父工程 -->
<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>2.7.0-M1</version>
</parent>
     <!-- 起步依赖 -->
<dependencies>
  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
</dependencies>
<!-- 插件 -->
<build>
  <plugins>
    <plugin>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

编写启动类

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

编写配置文件application.properties

#日志格式
logging.pattern.console=%d{MM/dd
HH:mm:ss.SSS} %clr(%-5level) 
---[%-15thread] %cyan(%-50logger{50}):%msg%n
#端口号
server.port=8888

运行启动类主方法,启动项目

 SpringBoot入门_编写Java代码

 之前搭建的SpringBoot项目已经都整合了SpringMVC,我们编写一
个控制器进行测试:

@Controller
public class MyController {
      @RequestMapping("/hello")
      @ResponseBody
      public String hello(){
          System.out.println("hellospringboot!");
          return "hello springboot!";
 }
}

 启动类在启动时会做注解扫描(@Controller、@Service、@Repository......),扫描位置为同包或者子包下的注解,所以我们要在启动类同级或同级包下编写代码。

 启动项目,访问http://localhost:8888/hello

 SpringBoot原理分析_起步依赖

 查看spring-boot-starter-parent起步依赖

按住 Ctrl 点击 pom.xml 中的 spring-boot-starter-parent ,跳转到了 spring-boot-
starter-parent
pom.xml ,发现 spring-boot-starter-parent 的父工程是 spring-boot-
dependencies

 

 进入 spring-boot-dependenciespom.xml 可以看到,一部分坐标的版本、
依赖管理、插件管理已经定义好,所以SpringBoot工程继承
spring-boot-starter-parent 后已经具备版本锁定等配置了。所以起步依赖
的作用就是进行依赖的传递。

 

 查看spring-boot-starter-web起步依赖

按住 Ctrl 点击 pom.xml 中的 spring-boot-starter-web ,跳转到了 spring-boot-starter-
web
的 pom.xml ,从 spring-boot-starter-web 的 pom.xml 中我们可以发现, spring-
boot-starter-web
就是将web开发要使用的 spring-web 、 spring-webmvc 等坐标进
行了打包,这样我们的工程只要引入 spring-boot-starter-web 起步依赖的坐
标就可以进行web开发了,同样体现了依赖传递的作用。

SpringBoot原理分析_自动配置

 查看注解 @SpringBootApplication 的源码 

 @SpringBootConfifiguration:等同与@Confifiguration, 既标注该类是Spring的一个配置类

@EnableAutoConfifiguration:SpringBoot自动配置功能 开启

 查看注解 @EnableAutoConfifiguration 的源码

查看注解 @EnableAutoConfifiguration 的源码 

 

 @Import(AutoConfifigurationImportSelector.class) 导入了   AutoConfifigurationImportSelector 类

 查看AutoConfifigurationImportSelector源码

 查看AutoConfifigurationImportSelector源码 

SpringFactoriesLoader.loadFactoryNames 方法的作用就是从 META-INF/spring.factories 文件中读取指定类对应的类名称列表 

 点开 spring-boot-autoconfigure 的 spring.factories 文件

有关配置类的信息如下:

 

上面配置文件存在大量的以 Configuration 为结尾的类名称,这些类 就是存有自动配置信息的类,而 SpringApplication 在获取这些类名后 再加载。

 我们 ServletWebServerFactoryAutoConfifiguration 为例来分析源码:

 @EnableConfifigurationProperties(ServerProperties.class) 代表加载 ServerProperties 服务器配置属性类。

进入 ServerProperties 类源码如下:

 prefifix = "server" 表示SpringBoot配置文件中的前缀,SpringBoot会 将配置文件中以server开始的属性映射到该类的字段中。所以配 置网络端口的方式为 server.port

 如果我们没有在配置文件中配置默认端口,SpringBoot就会读 取默认配置,而默认配置存放在 META-INF/spring-configuration-metadata.json 中,打开 spring-boot-autoconfigure 的 spring.factories 文件

 该文件中保存的就是所有默认配置信息。

 SpringBoot原理分析_核心注解

 

 @SpringBootApplication

标注是SpringBoot的启动类。 此注解等同于

@SpringBootConfiguration + @EnableAutoConfiguration + @ComponentScan 。

 @SpringBootConfiguration

@SpringBootConfiguration @Configuration 的派生注解,跟 @Configuration 功能一 致,标注这个类是一个配置类,只不过 @SpringBootConfigurationSpringboot的注解,而 @Configuration 是Spring的注解

 @EnableAutoConfiguration

SpringBoot自动配置注解。 等同于

@AutoConfigurationPackage + @Import(AutoConfigurationImportSelector.class)

 @AutoConfigurationPackage

自动扫描包的注解,它会自动扫描主类所在包下所有加了注解的类 (@Controller,@Service等),以及配置类 (@Configuration)。

@Import({AutoConfigurationImportSelector.class})

该注解会导入 AutoConfifigurationImportSelector 类对象,该对象会从 META-INF/spring.factories 文件中读取配置类的名称列表。 

@ComponentScan

该注解会扫描项目,自动装配一些项目启动需要的Bean。 

YAML文件_配置文件介绍 

 SpringBoot项目中,大部分配置都有默认值,但如果想替换默认配 置的话,就可以使用application.properties或者application.yml进 行配置。

SpringBoot默认会从resources目录下加载application.properties 或application.yml文件。其中,application.properties文件是键值 对类型的文件,之前一直在使用,所以我们不再对properties文件 进行阐述。

 https://docs.spring.io/spring-boot/docs/2.7.0-M1/reference/ htmlsingle/#application-properties.server可以查找配置文件 如何覆盖SpringBoot项目的默认配置。

 除了properties文件外,SpringBoot还支持YAML文件进行配置。 YAML文件的扩展名为 .yml 或 .yaml ,它的基本要求如下:

1 大小写敏感

2 使用缩进代表层级关系

3 相同的部分只出现一次

比如使用properties文件配置tomcat端口:  server.port=8888

而使用YAML文件配置tomcat端口: 

server:
 port: 8888

YAML文件_自定义配置简单数据

 除了覆盖默认配置,我们还可以在YAML文件中配置其他信息以便我 们在项目中使用。配置简单数据的方式如下:

 语法:

       数据名: 值

示例代码:

      name: baizhan

注意:value之前有一个空格

 YAML文件_自定义配置对象数据

 对象:

      属性名1: 属性值

      属性名2: 属性值

# 或者

对象: {属性名1: 属性值,属性名2: 属性值}

 示例代码:

# 学生1
student1:
 sex: female
 age: 10
 address: beijing


# 学生2
student2: {sex: female,age: 10,address: beijing}

 属性名前面的空格个数不限,在yml语法中,相同缩进代表同一 个级别,只要每个属性前的空格数一样即可。

 YAML文件_自定义配置集合数据

 语法

集合:

       - 值1

       - 值2

# 或者

集合: [值1,值2]

 示例代码

# 城市
city1:
 - beijing
 - tianjin
 - shanghai
 - chongqing


city2:
[beijing,tianjin,shanghai,chongqing]


# 集合中的元素是对象
students:
 - name: baizhan
   age: 18
   score: 100
 - name: shangxuetang
   age: 28
   score: 88
 - name: chengxuyuan
   age: 38
   score: 90

注意:值与之前的 - 之间存在一个空格

 YAML文件_读取配置文件的数据

使用@Value读取

 我们可以通过@Value注解将配置文件中的值映射到一个Spring管理 的Bean的字段上,用法如下:

 配置文件

name: baizhan


student:
 sex: female
 age: 10
 address: beijing


city1:
 - beijing
 - tianjin
 - shanghai
 - chongqing

students:
 - name: baizhan
   age: 18
   score: 100
 - name: shangxuetang
   age: 28
   score: 88
 - name: chengxuyuan
   age: 38
   score: 90

读取配置文件数据:

@Controller
public class YmlController1 {
    @Value("${name}")
    private String name;

    @Value("${student1.age}")
    private int age;

    @Value("${city1[0]}")
    private String city1;

    @Value("${students[0].score}")
    private double score1;

    @RequestMapping("/yml1")
    @ResponseBody
    public String yml1(){
        System.out.println(name);
        System.out.println(age);
        System.out.println(city1);
        System.out.println(score1);
        return "hello springboot!";
   }
}

@Value只能映射简单数据类型,不能将yaml文件中的对 象、集合映射到属性中。

 使用@ConfigurationProperties读取

通过 @ConfigurationProperties(prefifix="对象") 可以将配置文件中的配置自动与实 体进行映射,这样可以将yml文件中配置的对象属性直接映射到 Bean当中。 

 配置文件

user:
 id: 10001
 username: shangxuetang
 address:
   - beijing
   - tianjin
   - shanghai
   - chongqing
 grades:
   - subject: math
     score: 100
   - subject: english
     score: 90

实体类

public class Grade {
    private String subject;
    private double score;
    // 省略getter/setter/tostring
}

读取配置文件

@Controller
@ConfigurationProperties(prefix = "user")
public class YmlController2 {
    private int id;
    private String username;
    private List<String> address;
    private List<Grade> grades;
    @RequestMapping("/yml2")
    @ResponseBody
    public String yml2(){
        System.out.println(id);
        System.out.println(username);
        System.out.println(address);
        System.out.println(grades);
        return "hello springboot!";
   }
    public int getId() {
        return id;
   }
    public void setId(int id) {
        this.id = id;
}
    public String getUsername() {
        return username;
   }
    public void setUsername(String username) {
        this.username = username;
   }
    public List<String> getAddress() {
        return address;
   }
    public void setAddress(List<String> address) {
        this.address = address;
   }
    public List<Grade> getGrades() {
        return grades;
   }
    public void setGrades(List<Grade> grades) {
        this.grades = grades;
   }
}

YAML文件_占位符的使用

 

 YAML文件中可以使用 ${} 占位符,它有两个作用:

 使用配置文件中的值

编写配置文件

server:
 port: 8888
myconfig:
 myport: ${server.port}

读取配置文件

@Controller
public class YmlController3 {
    @Value("${myconfig.myport}")
    private int port;
    @RequestMapping("/yml3")
    @ResponseBody
    public String yml3(){
        System.out.println(port);
        return "hello springboot!";
   }
}

使用框架提供的方法

SpringBoot框架提供了一些生成随机数的方法可以在yml文件中使 用:

 

 用法如下:

# 随机生成tomcat端口
server:
 port: ${random.int(1024,9999)}

YAML文件_配置文件存放位置及优先级

 配置文件有如下存放位置:

  1.  项目根目录下
  2.  项目根目录下的/config子目录中
  3.  项目的resources目录中
  4.  项目的resources下的/config子目录中

这些目录下都可以存放两类配置文件,分别是 application.yml 和 application.properties ,这些配置文件的优先级从高到低依次为:

 项目根目录下的/config子目录中

  •        config/application.properties
  •        config/application.yml

项目根目录下

  •       application.properties
  •       application.yml

项目的resources下的/config子目录中

  •      resources/config/application.properties
  •      resources/config/application.yml

项目的resources目录中

  •     resources/application.properties
  •     resources/application.yml

优先级高的文件会覆盖优先级低的文件中的配置

 YAML文件_bootstrap配置文件

 SpringBoot中有两种容器对象,分别是bootstrap和application, bootstrap是应用程序的父容器,bootstrap加载优先于 applicaton。bootstrap配置文件主要对bootstrap容器进行配置, application配置文件是对applicaton容器进行配置。 bootstrap配置文件也同样支持properties和yml两种格式,主要用 于从外部引入Spring应用程序的配置。 bootstrap配置文件特征

  • boostrap由父ApplicationContext加载,比applicaton优先加载。
  • boostrap里面的属性不能被覆盖。

bootstrap与application的应用场景

  • application配置文件主要用于SpringBoot项目的自动化配 置。
  • bootstrap配置文件有以下几个应用场景。
  1. 使用Spring Cloud Config配置中心时,需要在bootstrap配置文件中添加连接到配置中 心的配置属性来加载外部配置中心的配置信息。
  2. 一些固定的不能被覆盖的属性。
  3. 一些加密/解密的场景。

SpringBoot注册web组件_注册Servlet 

 由于SpringBoot项目没有web.xml文件,所以无法在web.xml中注 册web组件,SpringBoot有自己的方式注册web组件。

 注册方式一

  • 编写servlet

@WebServlet("/first")
public class FirstServlet extends
HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("First Servlet........");
   }
}
  • 启动类扫描web组件
@SpringBootApplication
//SpringBoot启动时扫描注册注解标注的Web组件
@ServletComponentScan
public class Springbootdemo2Application {
    public static void main(String[] args)
       {
      
          SpringApplication.run(Springbootdemo2Application.class, args);
   }
}

 注册方式二 

  • 编写servlet

public class SecondServlet extends
HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("Second Servlet........");
   }
}
  • 使用配置类注册servlet

@Configuration
public class ServletConfig {
    //ServletRegistrationBean可以注册
      Servlet组件,将其放入Spring容器中即可注册Servlet
    @Bean
    public ServletRegistrationBean getServletRegistrationBean(){
        // 注册Servlet组件
        ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
        // 添加Servlet组件访问路径
        bean.addUrlMappings("/second");
        return bean;
   }
}

SpringBoot注册web组件_注册Filter

 注册方式一

  •  编写filter

@WebFilter(urlPatterns = "/first")
public class FirstFilter implements Filter
{
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进入First Filter");
      
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("离开First Filter");
   }
    @Override
    public void destroy() { }
}
  • 启动类扫描web组件
@SpringBootApplication
//SpringBoot启动时扫描注册注解标注的Web组件
@ServletComponentScan
public class Springbootdemo2Application {
    public static void main(String[] args)
  {
      
      SpringApplication.run(Springbootdemo2Appl ication.class, args);
   }
}

 注册方式二

  • 编写filter

public class SecondFilter implements
Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException { }
    
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("进入Second Filter");
      
    filterChain.doFilter(servletRequest,servletResponse);

    System.out.println("离开Second Filter");
   }
    @Override
    public void destroy() { }
}
  • 使用配置类注册filter

@Configuration
public class FilterConfig {
    @Bean
    public FilterRegistrationBean getFilterRegistrationBean(){
        // 注册filter组件
        FilterRegistrationBean bean =  new FilterRegistrationBean(new SecondFilter());
        // 添加过滤路径
        bean.addUrlPatterns("/second");
        return bean;
   }
}

SpringBoot注册web组件_注册Listener

 注册方式一 

  •        编写Listener
@WebListener
public class FirstListener implements
ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("First ListenerInit......");
   }
    @Override
    public void contextDestroyed(ServletContextEvent sce){
   }
}

启动类扫描web组件

@SpringBootApplication
//SpringBoot启动时扫描注册注解标注的Web组件
@ServletComponentScan
public class Springbootdemo2Application {
    public static void main(String[] args){       
      
     SpringApplication.run(Springbootdemo2Appl ication.class, args);
   }
}

注册方式二

  •  编写Listener
public class SecondListener implements
ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("Second Listener Init......");
   }
    @Override
    public void contextDestroyed(ServletContextEvent sce){
   }
}

使用配置类注册Listener

@Configuration
public class ListenerConfig {
    @Bean
    public ServletListenerRegistrationBean getServletListenerRegistrationBean(){
        ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(new SecondListener());
        return bean;
   }
}

SpringBoot访问静态资源_静态资源相关目录

 SpringBoot项目中没有WebApp目录,只有src目录。在 src/main/resources 下面有 statictemplates 两个文件夹。SpringBoot默认在 static 目录中存放静态资源,而 templates 中放动态页面。

static目录 

SpringBoot通过 /resources/static 目录访问静态资源,在 resources/static 中编 写html页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试html</title>
</head>
<body>
   <h1>我的HTML</h1>
   <img src="/img/img.png">
</body>
</html>

 目录结构

 templates目录

在SpringBoot中不推荐使用JSP作为动态页面,而是默认使用 Thymeleaf编写动态页面。templates目录是存放Thymeleaf页面的 目录,稍后我们讲解Thymeleaf技术。

SpringBoot访问静态资源_静态资源其他存放位置 

 除了 /resources/static 目录,SpringBoot还会扫描以下位置的静态资源:

/resources/META‐INF/resources/

/resources/resources/

/resources/public/

 

 我们还可以在配置文件自定义静态资源位置

 

 在SpringBoot配置文件进行自定义静态资源位置配置

spring:
 web:
   resources:
     static-locations:
classpath:/suibian/,classpath:/static/

注意:

1 该配置会覆盖默认静态资源位置,如果还想使用之前的静态资源位置,还需要配置在后面。

2 SpringBoot2.5之前的配置方式为: spring.resources.static-locations

 SpringBoot整合JSP

 在SpringBoot中不推荐使用JSP作为动态页面,我们要想使用JSP编 写动态页面,需要手动添加webapp目录。

  • 由于SpringBoot自带tomcat无法解析JSP,需要在pom文件添加 JSP引擎
<!--添加jsp引擎,SpringBoot内置的Tomcat不能解析JSP-->
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embedjasper</artifactId>
</dependency>
  • 创建webapp目录,编写JSP文件

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
    <h1>Hello JSP</h1>
  </body>
</html>
  • 将webapp标记为web目录

 

  •  修改配置文件,配置视图解析器

spring:
 mvc:
   view:
     prefix: /WEB-INF/jsp/
     suffix: .jsp
logging:
 pattern:
   console: "%d{MM/dd HH:mm:ss.SSS}
%clr(%-5level) --- [%-15thread]
%cyan(%-50logger{50}):%msg%n"
  • 创建Controller
@Controller
public class PageController {
    // 页面跳转
    @GetMapping("/{page}")
    public String showPage(@PathVariable String page){
        return page;
   }
}
  • 启动项目,访问http://localhost:8080/myJsp

 Thymeleaf_Thymeleaf入门

 Thymeleaf是一款用于渲染XML/HTML5内容的模板引擎,类似 JSP。它可以轻易的与SpringMVC等Web框架进行集成作为Web应 用的模板引擎。在SpringBoot中推荐使用Thymeleaf编写动态页 面。 Thymeleaf最大的特点是能够直接在浏览器中打开并正确显示模板 页面,而不需要启动整个Web应用。 Thymeleaf在有网络和无网络的环境下皆可运行,它即可以让美工 在浏览器查看页面的静态效果,也可以让程序员在服务器查看带数 据的动态页面效果。没有数据时,Thymeleaf的模板可以静态地运 行;当有数据返回到页面时,Thymeleaf标签会动态地替换掉静态内容,使页面动态显示。

 1 创建Springboot项目

 2 引入SpringMVC和Thymeleaf起步依赖

<!--添加Thymeleaf起步依赖-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
 </dependency>
 <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

 3 创建视图index.html

<!DOCTYPE html>
<!-- 引入thymeleaf命名空间,方便使用thymeleaf属性 -->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>thymeleaf入门</title>
</head>
<body>
   <!-- 静态页面显示程序员,动态页面使用后端传来的msg数据代替 -->
   <!-- thymeleaf支持el表达式 -->
   <h2 th:text="${msg}">程序员</h2>
</body>
</html>

4. template中的html文件不能直接访问,需要编写Controller跳转 到页面中

@Controller
public class PageController {
    // 页面跳转
    @GetMapping("/show")
    public String showPage(Model model){
        model.addAttribute("msg","Hello Thymeleaf");
        return "index";
   }
}

5.进行springboot配置

#日志格式

logging.pattern.console=%d{HH:mm:ss.SSS} %clr(%-5level) --- [%-15thread] %cyan(%-50logger{50}):%msg%n 

6.启动项目,访问http://localhost:8080/show及静态页面

 Thymeleaf_变量输出

 

 1.准备模型数据

@GetMapping("/show")
public String showPage(Model model){
    model.addAttribute("msg","Hello Thymeleaf");
    return "index";
}

 2.在视图展示model中的值

<span th:text="${msg}"></span>
<hr/>
<input th:value="${msg}">

Thymeleaf_操作字符串

 Thymeleaf提供了一些内置对象可以操作数据,内置对象可直接在 模板中使用,这些对象是以#引用的,操作字符串的内置对象为 strings。

 使用方式:

<span th:text="${#strings.isEmpty(msg)}"></span>
<hr/>
<span th:text="${#strings.contains(msg,'s')}"></span>
<hr/>
<span th:text="${#strings.length(msg)}"></span>

Thymeleaf_操作时间

 操作时间的内置对象为dates

方法说明
${#dates.format(key)}格式化日期,默认的以浏览器默认语言为格式化标准
${#dates.format(key,'yyyy/MM/dd')}按照自定义的格式做日期转换
${#dates.year(key)}取年
${#dates.month(key)}取月
${#dates.day(key)}取日

1.准备数据

model.addAttribute("date",new Date(130,01,01));

2.使用内置对象操作时间

<span th:text="${#dates.format(date)}"></span>
<hr/>
<span th:text="${#dates.format(date,'yyyy/MM/dd')}"></span>
<hr/>
<span th:text="${#dates.year(date)}"></span>
<span th:text="${#dates.month(date)}"></span>
<span th:text="${#dates.day(date)}"></span>

Thymeleaf_条件判断

 1.准备数据

model.addAttribute("sex","女");

2.进行条件判断

<div>
    <span th:if="${sex} == '男'">
       性别:男
    </span>
    <span th:if="${sex} == '女'">
       性别:女
    </span>
</div>

 1.准备数据

model.addAttribute("id","12");

 2.进行条件判断

<div th:switch="${id}">
    <span th:case="1">ID为1</span>
    <span th:case="2">ID为2</span>
    <span th:case="3">ID为3</span>
    <span th:case="*">ID为*</span>
</div>

 Thymeleaf_迭代遍历

 遍历集合

1.编写实体类

public class Users {
    private String id;
    private String name;
    private int age;
    // 省略getter/setter/构造方法
}

2.准备数据

List<Users> users = new ArrayList<>();
users.add(new Users("1","sxt",23));
users.add(new Users("2","baizhan",22));
users.add(new Users("3","admin",25));
model.addAttribute("users",users);

 3.在页面中展示数据

<table border="1" width="50%">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Age</th>
    </tr>
    <!-- 遍历集合的每一项起名为user -->
    <tr th:each="user : ${users}">
        <td th:text="${user.id}"></td>
        <td th:text="${user.name}"></td>
        <td th:text="${user.age}"></td>
    </tr>
</table>

使用状态变量

 thymeleaf将遍历的状态变量封装到一个对象中,通过该对象的属 性可以获取状态变量:

 

 使用状态变量

<!--冒号前的第一个对象是遍历出的对象,第二个对象是封装状态变量的对象-->
<tr th:each="user,status : ${users}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
    <td th:text="${status.index}"></td>
    <td th:text="${status.count}"></td>
    <td th:text="${status.size}"></td>
    <td th:text="${status.odd}"></td>
    <td th:text="${status.even}"></td>
    <td th:text="${status.first}"></td>
    <td th:text="${status.last}"></td>
</tr>

遍历Map

 1.准备数据

Map<String,Users> map = new HashMap<>();
map.put("user1",new
Users("1","shangxuetang",23));
map.put("user2",new
Users("2","baizhan",22));
map.put("user3",new
Users("3","admin",25));
model.addAttribute("map",map);

 2.遍历map

<table border="1" width="50%">
    <tr>
        <th>ID</th>
        <th>Name</th>
        <th>Age</th>
        <th>Key</th>
    </tr>
    <!-- 遍历出的是一个键值对对象,key获取键,value获取值 -->
    <tr th:each="m : ${map}">
        <td th:text="${m.value.id}"></td>
        <td th:text="${m.value.name}"></td>
        <td th:text="${m.value.age}"></td>
        <td th:text="${m.key}"></td>
    </tr>
</table>

 Thymeleaf_获取域中的数据

 thymeleaf也可以获取request,session,application域中的数 据,方法如下:

 1.准备数据

request.setAttribute("req","HttpServletRequest");
session.setAttribute("ses","HttpSession");
session.getServletContext().setAttribute("app","application");

 2.获取域数据

request1: <span th:text="${#request.getAttribute('req')}"/>
request2:<span th:text="${#httpServletRequest.getAttribute('req')}"/>
<hr/>
session1: <span th:text="${session.ses}"/>
session2: <span th:text="${#httpSession.getAttribute('ses')}"/>
<hr/>
application1: <span th:text="${application.app}"/>
application2:<span th:text="${#servletContext.getAttribute('app')}"/>

Thymeleaf_URL写法

 在Thymeleaf中路径的写法为 @{路径}

<a th:href="@{http://www.baidu.com}">百度</a>

 在路径中添加参数

1. 准备数据

model.addAttribute("id","100");
model.addAttribute("name","bzcxy");

2.准备跳转后访问的Controller

@GetMapping("/show2")
@ResponseBody
public String show2(String id,String name)
{
    return id+":"+name;
}

3.在URL中添加参数

<a th:href="@{show2?id=1&name=sxt}">静态参数一</a>
<a th:href="@{show2(id=2,name=bz)}">静态参数二</a>
<a th:href="@{'show2?id='+${id}+'&name='+${name}}">动态参数一</a>
<a th:href="@{show2(id=${id},name=${name})}">动态参数二</a>

在RESTful风格路径中添加参数

1.准备跳转后访问的Controller

@GetMapping("/show3/{id}/{name}")
@ResponseBody
public String show3(@PathVariable String
id,@PathVariable String name){
    return id+":"+name;
}

2.在URL中添加参数

<a th:href="@{/show3/{id}/{name} (id=${id},name=${name})}">restful格式传递参数方式</a>

Thymeleaf_相关配置

 在Springboot配置文件中可以进行Thymeleaf相关配置

spring:
 thymeleaf:
   prefix: classpath:/templates/
   suffix: .html
   encoding: UTF-8
   cache: false
   servlet:
     content-type: text/html

SpringBoot热部署

 热部署,就是在应用正在运行的时候升级软件,却不需要重新启动 应用。即修改完代码后不需要重启项目即可生效。在SpringBoot 中,可以使用DevTools工具实现热部署

1.添加DevTools依赖

<!-- 热部署工具 -->
<dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-bootdevtools</artifactId>
    <optional>true</optional>
</dependency>

 2.在idea中设置自动编译

 

 3.在Idea设置自动运行 快捷键 Ctrl+Shift+Alt+/ 后点击 Registry ,勾选 complier.automake.allow.when.app.running

 

 SpringBoot整合MyBatis

 

 Spring整合MyBatis时需要进行大量配置,而SpringBoot整合 MyBatis则可以简化很多配置:

 1.准备数据库数据

CREATE DATABASE `student`;
USE `student`;
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `sex` varchar(10) DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT
CHARSET=utf8;
insert  into
`student`(`id`,`name`,`sex`,`address`)
values (1,'程序员','男','北京'),(2,'北京','女','北京');

创建SpringBoot项目,添加MyBatis起步依赖和Mysql驱动依赖

<dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starterweb</artifactId>
</dependency>
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-bootstarter</artifactId>
    <version>2.2.1</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connectorjava</artifactId>
    <scope>runtime</scope>
</dependency>
<dependency> 
<groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-startertest</artifactId>
    <scope>test</scope>
</dependency>

3.编写实体类

public class Student {
    private int id;
    private String name;
    private String sex;
    private String address;
    
    // 省略构造方法/getter/setter/tostring
}

 4.编写Mapper接口

@Mapper
public interface StudentMapper {
    List<Student> findAll();
}

5.编写Mapper映射文件

<?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.itbaizhan.springbootmybatis.mapper.StudentMapper">
    <select id="findAll" resultType="student">
       select * from student
    </select>
</mapper>

6.编写配置文件

# 数据源
spring:
 datasource:
   driver-class-name: com.mysql.cj.jdbc.Driver
   url: jdbc:mysql:///student?serverTimezone=UTC
   username: root
   password: root
   # mybatis配置
mybatis:
  # 映射文件位置
 mapper-locations: com/itbaizhan/springbootmybatis/mapper/*Mapper.xml
  # 别名
 type-aliases-package: com.itbaizhan.springbootmybatis.domain
  
#日志格式
logging:
 pattern:
 console: '%d{HH:mm:ss.SSS}
%clr(%-5level) --- [%-15thread]
%cyan(%-50logger{50}):%msg%n'

7. 编写测试类

// 测试类注解,可以在运行测试代码时加载Spring容器
@SpringBootTest
public class StudentMapperTest {
    @Autowired
    private StudentMapper studentMapper;
    @Test
    public void testFindAll(){
        List<Student> all = studentMapper.findAll();
        all.forEach(System.out::println);
   }
}

 SpringBoot参数校验_简单数据类型

 SpringBoot自带了validation工具可以从后端对前端传来的参数进 行校验,用法如下:

 1.引入 validation 起步依赖

<!-- 参数校验 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-startervalidation</artifactId>
</dependency>

2.编写Controller

// 该控制器开启参数校验
@Validated
@Controller
public class TestController {
    @RequestMapping("/t1")
    @ResponseBody
    // 在参数前加校验注解,该注解的意思是字符串参数不能为null
    public String t1(@NotBlank String username){
        System.out.println(username);
        return "请求成功!";
   }
}

3.访问http://localhost:8080/t1,发现当没有传来参数时,会抛 出 ConstraintViolationException 异常。

4.在校验参数的注解中添加 message 属性,可以替换异常信息。 

// 该控制器开启参数校验
@Validated
@Controller
public class TestController {
    @RequestMapping("/t1")
    @ResponseBody
    // 在参数前加校验注解,该注解的意思是字符串参数不能为null
    public String t1(@NotBlank(message = "用户名不能为空") String username){
        System.out.println(username);
        return "请求成功!";
   }
}

 SpringBoot参数校验_异常处理

 当抛出 ConstraintViolationException 异常后,我们可以使用SpringMVC的异 常处理器,也可以使用SpringBoot自带的异常处理机制。 当程序出现了异常,SpringBoot会使用自带的 BasicErrorController 对象处 理异常。该处理器会默认跳转到/resources/templates/error.html 页面。

编写异常页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>错误页面</title>
</head>
<body>
   <h1>服务器开小差了!</h1>
</body>
</html>

SpringBoot参数校验_校验相关注解

@RequestMapping("/t2")
@ResponseBody
public String t2(
        @NotBlank @Length(min = 1, max = 5) String username,
        @NotNull @Min(0) @Max(150) Integer age,
        @NotEmpty @RequestParam List<String> address,
        @NotBlank @Email String email) {
    System.out.println(username);
    System.out.println(age);
    System.out.println(address);
    System.out.println(email);
    return "请求成功!";
}

 SpringBoot参数校验_对象类型

 SpringBoot也可以校验对象参数中的每个属性,

用法如下: 1 添加实体类

public class Student {
    @NotNull(message = "id不能为空")
    private Integer id;
    @NotBlank(message = "姓名不能为空")
    private String name;
    // 省略getter/setter/tostring
}

 2.编写控制器

@Controller
public class TestController2 {
    @RequestMapping("/t3")
    @ResponseBody
    // 校验的对象参数前添加@Validated,并将异常信息封装到BindingResult对象中
    public String t3(@Validated Student  student,BindingResult result) {
        // 判断是否有参数异常
        if (result.hasErrors()) {
            // 所有参数异常
            List<ObjectError> list =  result.getAllErrors();
             // 遍历参数异常,输出异常信息
            for (ObjectError err : list) {
                FieldError fieldError = (FieldError) err;
              
            System.out.println(fieldError.getDefaultMessage());
           }
            return "参数异常";
       }
        System.out.println(student);
        return "请求成功!";
   }
}

SpringBoot指标监控_添加Actuator功能

 Spring Boot Actuator可以帮助程序员监控和管理SpringBoot应 用,比如健康检查、内存使用情况统计、线程使用情况统计等。我 们在SpringBoot项目中添加Actuator功能,即可使用Actuator监控 项目,用法如下:

 1.在被监控的项目中添加Actuator起步依赖

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

2.编写配置文件

#开启所有监控端点
management.endpoints.web.exposure.include= *

 3.访问项目:http://localhost:8080/actuator

 通过URL可以调用actuator的功能:

 SpringBoot指标监控_Spring Boot Admin

 Actuator使用JSON格式展示了大量指标数据,不利于我们查看,我 们可以使用可视化工具Spring Boot Admin查看actuator生成指标 数据。Spring Boot Admin是一个独立的项目,我们需要创建并运 行该项目。

 创建Spring Boot Admin服务端项目

1.创建SpringBoot项目,添加SpringMVC和Spring Boot Admin服 务端起步依赖

<dependency>  
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>

2.修改配置文件

# 端口号
server.port=9090
#日志格式
logging.pattern.console=%d{HH:mm:ss.SSS}
%clr(%-5level) --- [%-15thread]
%cyan(%-50logger{50}):%msg%n

3.修改启动类

@SpringBootApplication
@EnableAdminServer //开启Spring Boot Admin
服务端
public class MyadminApplication {
    public static void main(String[] args)
     {
      
      SpringApplication.run(MyadminApplication.class, args);
     }
}

连接Spring Boot Admin项目 在被监控的项目中连接Spring Boot Admin项目,才能使用Spring Boot Admin查看指标数据。

 1.被监控项目添加Spring Boot Admin客户端起步依赖

<dependency>
    <groupId>de.codecentric</groupId>
    <artifactId>spring-boot-admin-starter-client</artifactId>
    <version>2.6.0</version>
</dependency>

2.修改配置文件

#Spring boot admin访问地址
spring.boot.admin.client.url=http://localhost:9090

3.此时Spring Boot Admin即可连接被监控的项目

 SpringBoot日志管理

SpringBoot默认使用Logback组件作为日志管理。Logback是log4j 创始人设计的一个开源日志组件。在SpringBoot项目中我们不需要 额外的添加Logback的依赖,因为在 spring-boot-parent 中已经包含了 Logback的依赖。 

 1.在 /resources 下添加Logback配置文件logback.xml

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--定义日志文件的存储地址-->
    <property name="LOG_HOME" value="${catalina.base}/logs/"/>
    
    <!-- 控制台输出 -->
    <appender name="Stdout"  class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志输出编码 -->
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level%logger{50} - %msg%n
            </pattern>
        </layout>
    </appender>
    
    <!-- 按照每天生成日志文件 -->
    <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBas edRollingPolicy">
            <!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yy 99-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <layout class="ch.qos.logback.classic.PatternLayout">
            <!--格式化输出:%d表示时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
            </pattern>
        </layout>
        <!--日志文件最大的大小-->
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
          
<MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>
    <!-- 日志输出级别 -->
    <root level="info">
        <appender-ref ref="Stdout"/>
        <appender-ref ref="RollingFile"/>
    </root>
</configuration>

 注:Logback配置文件名为logback-test.xml或 logback.xml,如果classpath下没有这两个文件,LogBack 会自动进行最小化配置。

 2.在代码中打印日志

@Controller
public class LogbackController {
    private final static Logger logger = LoggerFactory.getLogger(LogbackController.class);
    @RequestMapping("/printLog")
    @ResponseBody
    public String showInfo(){
        logger.info("记录日志");
        return "Hello Logback";
   }
}

3.如果日志过多,可以屏蔽一些包的日志,在配置文件中配置

#屏蔽org包中的日志输出
logging.level.org=off

补充:Log4j2安全漏洞 在2021年12月,Log4j2爆出了极其严重的安全漏洞,攻击者可 以让记录的日志包含指定字符串,从而执行任意程序。很多大 型网站,如百度等都是此次Log4j漏洞的受害者,很多互联网企 业连夜做了应急措施。 Log4j2.0到2.14.1全部存在此漏洞,危害范围极其广泛, Log4j2.15.0-rc1中修复了这个 bug。

因Log4j2漏洞的反复无常,导致某些公司已经切换到Logback 来记录日志,但在Log4j2漏洞爆出后,Logback也爆出漏洞: 在Logback1.2.7及之前的版本中,具有编辑配置文件权限的攻 击者可以制作恶意配置,允许从LDAP服务器加载、执行任意代 码。 解决方案为将Logback升级到安全版本: Logback1.2.9+ SpringBoot2.6.2以上的Logback版本已经升到了1.2.9,Log4j2 的版本也升到了2.17.0,所以我们使用SpringBoot2.6.2以上版 本无需担心Log4j2和Logback安全漏洞。

 SpringBoot项目部署_项目打包

SpringBoot项目是依赖于Maven构建的,但打包时如果只依赖 Maven打包工具则会打包不完整,我们还需要在SpringBoot项目中 引入SpringBoot打包插件 : 

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-mavenplugin</artifactId>
        </plugin>
    </plugins>
</build>

此时再使用Maven插件打包:

 

打包后jar包解压目录如下: 

 

 可以看到该目录少了BOOT-INF,打包是不完整的,也无法运行jar 包

运行jar包:

1 进入jar包所在目录,使用cmd打开命令行窗口

2 输入命令:

java -jar jar包名

 SpringBoot项目部署_多环境配置

 

 在真实开发中,在不同环境下运行项目往往会进行不同的配置,比 如开发环境使用的是开发数据库,测试环境使用的是测试数据库, 生产环境使用的是生产数据库。SpringBoot支持不同环境下使用不 同的配置文件,用法如下:

 配置文件名:

    application-环境名.properties/yml   

如:

  1 application-dev.properties/yml 开发环境配置文件

    

# 开发环境端口号为8080
server:
 port: 8080

  2 application-test.properties/yml 测试环境配置文件

  

# 测试环境端口号为8081
server:
 port: 8081

3 application-prod.properties/yml 生产环境配置文件

# 生产环境端口号为80
server:
 port: 80

 运行jar包时选择环境:

 java -jar jar包名 --spring.profiles.active=环 境名

 SpringBoot容器化部署_安装Docker环境

 为了节约资源,在生产环境中我们更多的是使用Docker容器部署 SpringBoot应用,首先我们准备Docker环境:

1 准备一台centos7系统的虚拟机,连接虚拟机。

2 关闭虚拟机防火墙

# 关闭运行的防火墙
systemctl stop firewalld.service
# 禁止防火墙自启动
systemctl disable firewalld.service

3. 安装Docker

# 安装Docker
yum -y install docker
# 启动docker
systemctl start docker

SpringBoot容器化部署_Dockerfile制作镜像

由于在SpringBoot中嵌入了Web容器,所以在制作SpringBoot项目 的镜像时无需依赖Web容器,基于JDK制作镜像即可,接下来我们 使用Dockerfile制作镜像:

1.进入opt目录

cd /opt

2 使用rz命令将项目Jar包上传至虚拟机

3 编写DockerFile

cat <<EOF > Dockerfile
# 基于JDK11
FROM openjdk:11
# 作者
MAINTAINER itbaizhan
# 拷贝到容器opt目录
ADD springbootdemo7-0.0.1-SNAPSHOT.jar
/opt
#保留端口
EXPOSE 8080
# 启动容器后执行的命令
CMD java -jar /opt/springbootdemo7-0.0.1-
SNAPSHOT.jar --spring.profiles.active=dev
EOF

4.构建镜像

 docker build -t springbootdocker .

5.查看所有的镜像,出现springbootdocker代表镜像构建成功

docker images

6.使用镜像启动容器

docker run -d -p 8080:8080
springbootdocker

7.访问ip地址:8080/printLog查看是否启动成功

SpringBoot容器化部署_Maven插件制作镜像 

 除了DockerFile,我们还可以使用Maven插件制作镜像。使用方法 如下:

1.开启远程docker服务

# 修改docker配置文件
vim /lib/systemd/system/docker.service
# 在ExecStart=后添加配置,远程访问docker的端口
为2375
ExecStart=/usr/bin/dockerd-current -H
tcp://0.0.0.0:2375 -H
unix://var/run/docker.sock 
          --add-runtime dockerrunc=/usr/libexec/docker/docker-runccurrent 
          --default-runtime=docker-runc 
          --exec-opt
          native.cgroupdriver=systemd 
          --userland-proxypath=/usr/libexec/docker/docker-proxycurrent 
          --initpath=/usr/libexec/docker/docker-initcurrent 
          --seccompprofile=/etc/docker/seccomp.json 
          $OPTIONS 
          $DOCKER_STORAGE_OPTIONS 
          $DOCKER_NETWORK_OPTIONS 
          $ADD_REGISTRY 
          $BLOCK_REGISTRY 
          $INSECURE_REGISTRY 
          $REGISTRIES
# 重启docker
systemctl daemon-reload
systemctl restart docker

2.在项目的pom文件中添加 docker-maven-plugin 插件

<!-- docker-maven-plugin-->
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-mavenplugin</artifactId>
    <version>1.2.2</version>
    <configuration>
        <!-- Docker路径 -->
    <dockerHost>http://192.168.25.101:2375</dockerHost>
        <!-- Dockerfile定义 -->
        <baseImage>openjdk:11</baseImage>
        <!-- 作者 -->
        <maintainer>itbaizhan</maintainer>
        <resources>
            <resource>
                <!-- 复制jar包到docker容器指定目录 -->
                <targetPath>/</targetPath>
                <!-- 从哪个包拷贝文件,target包 -->
              
                <directory>${project.build.directory}
                </directory>
                <!-- 拷贝哪个文件 -->
              
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
        <workdir>/</workdir>
        <entryPoint>["java", "-jar","${project.build.finalName}.jar","--spring.profiles.active=dev"]</entryPoint>
        <forceTags>true</forceTags>
        <!-- 镜像名 -->
        <imageName>${project.artifactId}
        </imageName>
        <!-- 镜像版本 -->
        <imageTags>
            <imageTag>${project.version}
        </imageTag>
        </imageTags>
    </configuration>
</plugin>

3.使用maven的package命令给项目打包

4.使用maven的docker插件制作镜像

 5.查看所有的镜像,出现springbootdemo7代表镜像构建成功

docker images

6.使用镜像启动容器

docker run -d -p 8081:8080
springbootdemo7:0.0.1-SNAPSHOT

 Spring Task_定时任务

 定时任务即系统在特定时间执行一段代码,它的场景应用非常广 泛:

1 购买游戏的月卡会员后,系统每天给会员发放游戏资源。

2 管理系统定时生成报表。

3 定时清理系统垃圾。

4 ......

定时任务的实现主要有以下几种方式:

1. Java自带的java.util.Timer类,这个类允许调度一个java.util.TimerTask任务。使用这种方式可以让 程序按照某一个频度执行,但不能在指定时间运行。一般用的较少。

2 Quartz。这是一个功能比较强大的的调度器,可以让程序在指定时间执行,也可以按照某一个频度 执行,配置起来稍显复杂。

3  Spring3.0以后自带Spring Task,可以将它看成一个轻量级的Quartz,使用起来比 Quartz简单许 多,在课程中我们使用Spring Task实现定时任务

Spring Task_入门案例 

1.创建SpringBoot项目,在启动类开启定时任务。

@SpringBootApplication
@EnableScheduling
public class Springbootdemo8Application {
    public static void main(String[] args)
   {
      
       SpringApplication.run(Springbootdemo8Application.class, args);
   }
}

2.编写定时任务类

@Component
public class MyTask {
    // 定时任务方法,每秒执行一次
    @Scheduled(cron="* * * * * *")
    public void task1() {
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        System.out.println(sdf.format(new Date()));
   }
}

3.启动项目,定时任务方法按照配置定时执行。

 Spring Task_Cron表达式

 

Spring Task依靠Cron表达式配置定时规则。Cron表达式是一个字 符串,分为6或7个域,每一个域代表一个含义,以空格隔开。有如 下两种语法格式: 

1.Seconds Minutes Hours DayofMonth Month DayofWeek Year

2 Seconds Minutes Hours DayofMonth Month DayofWeek

 

 Spring Task_Cron实战案例

 

 Spring Task_@Scheduled

 @Scheduled写在方法上方,指定该方法定时执行。常用参数如 下:

      cron:cron表达式,定义方法执行的时间规则。

      fixedDelay:任务立即执行,之后每隔多久执行一次,单位是毫 秒,上一次任务结束后计算下次执行的时间。

// 立即执行,任务结束后每5秒执行一次
@Scheduled(fixedDelay=5000)
public void task1() throws
InterruptedException {
    SimpleDateFormat sdf = new  SimpleDateFormat("HH:mm:ss");
    Thread.sleep(1000);
    System.out.println(sdf.format(new Date()));
}

 fixedRate:任务立即执行,之后每隔多久执行一次,单位是毫 秒,上一次任务开始后计算下次执行的时间。

// 立即执行,之后每5秒执行一次
@Scheduled(fixedRate=5000)
public void task2() throws
InterruptedException {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    Thread.sleep(1000);
    System.out.println(sdf.format(new Date()));
}

initialDelay:项目启动后不马上执行定时器,根据initialDelay 的值延时执行。

// 项目启动3秒后执行,之后每5秒执行一次。
@Scheduled(fixedRate=5000,initialDelay =
3000)
public void task3() throws
InterruptedException {
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    Thread.sleep(1000);
    System.out.println(sdf.format(new Date()));
}

Spring Task_多线程任务

Spring Task定时器默认是单线程的,如果项目中使用多个定时器, 使用一个线程会造成效率低下。代码如下: 

@Scheduled(cron="* * * * * *")
private void task1() throws
InterruptedException {
  
System.out.println(Thread.currentThread().getId()+"线程执行任务1");
    Thread.sleep(5000);
}
@Scheduled(cron="* * * * * *")
private void task2() {
  
System.out.println(Thread.currentThread().getId()+"线程执行任务2");
}

任务1较浪费时间,会阻塞任务2的运行。此时我们可以给Spring Task配置线程池。

最后

以上就是霸气乐曲为你收集整理的SpringBoot介绍SpringBoot目录 SpringBoot介绍_Spring缺点分析 SpringBoot介绍_什么是SpringBoot SpringBoot介绍_SpringBoot核心功能 SpringBoot入门_通过官网搭建项目 SpringBoot入门_通过IDEA脚手架搭建项目 SpringBoot入门_SpringBoot项目结构SpringBoot入门_通过Maven搭建项目 SpringBoot入门_编写Java代码 SpringBoot原理分析_起步依赖Spri的全部内容,希望文章能够帮你解决SpringBoot介绍SpringBoot目录 SpringBoot介绍_Spring缺点分析 SpringBoot介绍_什么是SpringBoot SpringBoot介绍_SpringBoot核心功能 SpringBoot入门_通过官网搭建项目 SpringBoot入门_通过IDEA脚手架搭建项目 SpringBoot入门_SpringBoot项目结构SpringBoot入门_通过Maven搭建项目 SpringBoot入门_编写Java代码 SpringBoot原理分析_起步依赖Spri所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部