概述
目录
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-dependencies 的 pom.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 功能一 致,标注这个类是一个配置类,只不过 @SpringBootConfiguration 是 Springboot的注解,而 @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文件_配置文件存放位置及优先级
配置文件有如下存放位置:
- 项目根目录下
- 项目根目录下的/config子目录中
- 项目的resources目录中
- 项目的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配置文件有以下几个应用场景。
- 使用Spring Cloud Config配置中心时,需要在bootstrap配置文件中添加连接到配置中 心的配置属性来加载外部配置中心的配置信息。
- 一些固定的不能被覆盖的属性。
- 一些加密/解密的场景。
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 下面有 static 和 templates 两个文件夹。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所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复