SpringBoot(看这一篇就够了)

打印 上一主题 下一主题

主题 526|帖子 526|积分 1578


SpringBoot

Spring的缺点

Spring是一个非常良好的轻量级框架,以IOC(控制反转)和AOP(面向切面)为思想内核,极大简化了JAVA企业级项目的开发。
固然Spring的组件代码是轻量级的,但它的配置却是重量级的。使用Spring进行项目开发需要在配置文件中写很多代码,全部这些配置都代表了开发时的斲丧。
除此之外,Spring项目的依赖管理也是一件耗时耗力的事变。在环境搭建时,需要分析要导入哪些库的坐标,而且还需要分析导入与之有依赖关系的其他库的坐标,一旦选错了依赖的版本,随之而来的不兼容问题就会严峻拦阻项目的开发进度。好比Spring5.0以上只能使用Junit4.12以上的版本。
总结起来,Spring的缺点就是:


  • 配置过于繁琐。
  • 引入的依赖过多,版本控制复杂。
什么是SpringBoot?

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


  • 配置简朴
  • 依赖引入简朴
  • 提供了一些大型项目的非功能特性,如嵌入式服务器,安全指标,健康监测等。
主动配置
SpringBoot项目主动提供最优配置,同时可以修改默认值满意特定的要求。
起步依赖
SpringBoot的依赖是基于功能的,而不是平凡项目的依赖是基于JAR包的。SpringBoot将完成一个功能所需要的全部坐标打包到一起,并完成了版本适配,我们在使用某功能时只需要引入一个依赖即可。
Springboot3 版本要求

然使用SpringBoot是需要肯定版本要求的:
工具版本要求IDEA2021.2.1+Java17+Maven3.5+Tomcat10.0+Servlet5.0+GraalVM(原生镜像功能) Community 22.3+Native Build Tools(原生镜像功能)0.9.19+ 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包即可。
  3.解压生成的SpringBoot项目
4.在Idea中打开解压的SpringBoot项目即可
通过IDEA脚手架搭建

我们也可以在IDEA中使用脚手架工具搭建项目:
1.在IDEA中新建项目,项目类型为Spring Initializr,写项目名、存放位置、语言类型、项目类型、JDK版本等。点击下一步。
   注意:这里肯定要将项目类型改为Maven
  

2. 选择SpringBoot版本和需要的起步依赖,创建。

3.完成项目搭建
通过Maven搭建项目

不管是通过官网,照旧通过脚手架搭建项目,都需要连接SpringBoot官网,但国内与SpringBoot官网连接并不稳固,此时我们也可以使用Maven手动搭建SpringBoot项目:
1.创建新项目

2.在pom中添加项目的父工程、起步依赖、插件、依赖和插件的下载所在
  1. <!-- 父工程 -->
  2. <parent>
  3.   <groupId>org.springframework.boot</groupId>
  4.   <artifactId>spring-boot-starter-parent</artifactId>
  5.   <version>3.1.2</version>
  6. </parent>
  7. <!-- 起步依赖 -->
  8. <dependencies>
  9.   <dependency>
  10.     <groupId>org.springframework.boot</groupId>
  11.     <artifactId>spring-boot-starter-web</artifactId>
  12.   </dependency>
  13.   <dependency>
  14.     <groupId>org.springframework.boot</groupId>
  15.     <artifactId>spring-boot-starter-test</artifactId>
  16.     <scope>test</scope>
  17.   </dependency>
  18. </dependencies>
  19. <!-- 插件 -->
  20. <build>
  21.   <plugins>
  22.     <plugin>
  23.       <groupId>org.springframework.boot</groupId>
  24.       <artifactId>spring-boot-maven-plugin</artifactId>
  25.     </plugin>
  26.   </plugins>
  27. </build>
复制代码
3.编写启动类
  1. @SpringBootApplication
  2. public class SpringBootApp {
  3.   public static void main(String[] args) {
  4.     SpringApplication.run(SpringBootApp.class, args);
  5.    }
  6. }
复制代码
4.编写配置文件application.properties
  1. #日志格式
  2. logging.pattern.console=%d{MM/dd HH:mm:ss.SSS} %clr(%-5level) ---  [%-15thread] %cyan(%-50logger{50}):%msg%n
  3. #端口号
  4. server.port=8889
复制代码
5.运行启动类主方法,启动项目
SpringBoot的项目结构


src.main.java
这个目录下存放的是Java代码,在我们写好的包名下,SprinBoot生成了一个启动类,启动类的作用是启动SpringBoot项目,运行启动类的main方法即可启动SpringBoot项目。
src.main.resources
这个目录下存放的是配置文件和页面相关的代码,SpringBoot默认在static目录中存放静态资源,如css、js、图片等等。而templates中存放模板引擎,如jsp、thymeleaf等。
由于SpringBoot极大简化了Spring配置,所以只有一个application.properties配置文件,Spring的主动配置功能使得大部分的配置都有默认配置,该文件的功能是覆盖默认配置信息,该文件不写任何信息都可以启动项目。
启动后默认端口号为8080,我们可以覆盖该配置:
  1. server.port=8888
复制代码
src.test.java
这个目录下编写的是测试代码
pom文件
1.SpringBoot项目必须继续spring-boot-starter-parent,即全部的SpringBoot项目都是spring-boot-starter-parent的子项目。spring-boot-starter-parent中定义了常用配置、依赖、插件等信息,供SpringBoot项目继续使用。
  1. <parent>
  2.   <groupId>org.springframework.boot</groupId>
  3.   <artifactId>spring-boot-starter-parent</artifactId>
  4.   <version>3.1.2</version>
  5.   <relativePath/> <!-- lookup parent from repository -->
  6. </parent>
复制代码
2.SpringBoot项目中可以定义起步依赖,起步依赖不是以jar包为单元,而是以功能为单元
  1. <dependencies>
  2.   <dependency>
  3.     <groupId>org.springframework.boot</groupId>
  4.     <artifactId>spring-boot-starter-web</artifactId>
  5.   </dependency>
  6.   <dependency>
  7.     <groupId>org.springframework.boot</groupId>
  8.     <artifactId>spring-boot-starter-test</artifactId>
  9.     <scope>test</scope>
  10.   </dependency>
  11. </dependencies>
复制代码
3.spring-boot-maven-plugin插件是将项目打包成jar包的插件。该插件打包后的SpringBoot项目无需依赖web容器,可以直接使用JDK运行
  1. <build>
  2.   <plugins>
  3.     <plugin>
  4.       <groupId>org.springframework.boot</groupId>
  5.       <artifactId>spring-boot-maven-plugin</artifactId>
  6.     </plugin>
  7.   </plugins>
  8. </build>
复制代码
编写一个测试代码

之前搭建的SpringBoot项目已经都整合了SpringMVC,我们编写一个控制器进行测试:
  1. @Controller
  2. public class MyController {
  3.   @RequestMapping("/hello")
  4.   @ResponseBody
  5.   public String hello(){
  6.     System.out.println("hello springboot!");
  7.     return "hello springboot!";
  8.    }
  9. }
复制代码
启动类在启动时会做注解扫描(@Controller、@Service、@Repository…),扫描位置为同包大概同级包下的注解,所以我们要在启动类同级或同级包下编写代码。

启动项目,访问http://localhost:8889/hello
YAML文件

SpringBoot项目中,大部分配置都有默认值,但如果想更换默认配置的话,可以使用application.properties文件进行配置。properties文件是键值对类型的文件,之前不停在使用,所以我们不再对properties文件进行论述。
   https://docs.spring.io/spring-boot/docs/3.1.2/reference/htmlsingle/#appendix.application-properties
可以查找配置文件如何覆盖SpringBoot项目的默认配置。
  除了properties文件外,SpringBoot还支持YAML文件进行配置。YAML文件的扩展名为.yml或.yaml。SpringBoot默认会从resources目录下加载application.properties或application.yml文件。
YAML文件的基本要求如下:


  • 巨细写敏感
  • 使用缩进代表层级关系
  • 同级配置必须对齐,上下级配置必须缩进,但缩进的空格数不限。
  • 相同的部分只出现一次
  • 冒号和值之间必须要有空格
好比使用properties文件配置tomcat端口以及项目路径:
  1. server.port=8888
  2. server.servlet.context-path=/jjy
复制代码
而使用YAML文件配置tomcat端口:
  1. server:
  2.   servlet:
  3.    context-path: /jjy
  4.   port: 8888
复制代码
自定义配置文件

配置简朴数据
语法:
  1. 数据名: 值
复制代码
示例代码:
  1. email: jjy@qq.com
复制代码
配置对象数据
语法:
  1. 对象:
  2.     属性名1: 属性值
  3.     属性名2: 属性值
  4. # 或者
  5. 对象: {属性名1: 属性值,属性名2: 属性值}
复制代码
示例代码:
  1. # 邮箱1my1:  email: jjy@qq.com
  2.   password: jjy# 邮箱2my2: {email: jjyss@qq.com,password: jjyss}
复制代码
配置聚集数据
语法
  1. 集合:
  2.     - 值1
  3.     - 值2
  4.    
  5. # 或者
  6. 集合: [值1,值2]
复制代码
示例代码
  1. # 城市city1:  - beijing  - shanghai  - tianjin  - chongqingcity2: [beijing,tianjin,shanghai,chongqing]# 聚集中的元素是对象sxt:  - address: beijing   mobile: 13888888888   email: jjy@qq.com
  2.   - address: shanghai   mobile: 13777777777   email: jjyss@qq.com  - address: guangzhou   mobile: 13666666666   email: jjyaa@qq.com
复制代码
@Value读取配置文件

读取自定义配置时,我们可以通过@Value注解将配置文件中的值映射到一个Spring管理的Bean的字段上,用法如下:
配置文件
  1. email: jjy@qq.com
  2. my1:  email: jjy@qq.com
  3.   password: ijjycity1:  - beijing  - shanghai  - tianjin  - chongqingsxt:  - address: beijing   mobile: 13888888888   email: jjy@qq.com
  4.   - address: shanghai   mobile: 13777777777   email: jjysss@qq.com  - address: guangzhou   mobile: 13666666666   email: jjyaaa@qq.com
复制代码
读取配置文件数据
  1. @Controller
  2. public class YmlController1 {
  3.   @Value("${email}")
  4.   private String email;
  5.   @Value("${my1.password}")
  6.   private String password;
  7.   @Value("${city1[0]}")
  8.   private String city1;
  9.   @Value("${sxt[1].mobile}")
  10.   private String mobile;
  11.   @RequestMapping("/yml1")
  12.   @ResponseBody
  13.   public String yml1(){
  14.     return email+":"+password+":"+city1+":"+mobile;
  15.    }
  16. }
复制代码
  @Value只能映射简朴数据类型,不能将yaml文件中的对象、聚集映射到属性中。
  @ConfigurationProperties读取配置文件

通过@ConfigurationProperties(prefifix="对象")可以将配置文件中的配置主动与实体进行映射,如许可以将yml文件中配置的对象属性直接映射到Bean当中。
配置文件
  1. user:
  2.   id: 10001
  3.   username: shangxuetang
  4.   address:
  5.    - beijing
  6.    - tianjin
  7.    - shanghai
  8.    - chongqing
  9.   grades:
  10.    - subject: math
  11.     score: 100
  12.    - subject: english
  13.     score: 90
复制代码
实体类
  1. public class Grade {
  2.   private String subject;
  3.   private double score;
  4.   // 省略getter/setter/tostring
  5. }
复制代码
读取配置文件
  1. @Controller
  2. @ConfigurationProperties(prefix = "user")
  3. public class YmlController2 {
  4.   private int id;
  5.   private String username;
  6.   private List<String> address;
  7.   private List<Grade> grades;
  8.   @RequestMapping("/yml2")
  9.   @ResponseBody
  10.   public String yml2(){
  11.     System.out.println(id);
  12.     System.out.println(username);
  13.     System.out.println(address);
  14.     System.out.println(grades);
  15.     return "hello springboot!";
  16.    }
  17.   public int getId() {
  18.     return id;
  19.    }
  20.   public void setId(int id) {
  21.     this.id = id;
  22.    }
  23.   public String getUsername() {
  24.     return username;
  25.    }
  26.   public void setUsername(String username) {
  27.     this.username = username;
  28.    }
  29.   public List<String> getAddress() {
  30.     return address;
  31.    }
  32.   public void setAddress(List<String> address) {
  33.     this.address = address;
  34.    }
  35.   public List<Grade> getGrades() {
  36.     return grades;
  37.    }
  38.   public void setGrades(List<Grade> grades) {
  39.     this.grades = grades;
  40.    }
  41. }
复制代码
SpringBoot整合Web开发

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

1.编写servlet
  1. @WebServlet("/first")
  2. public class FirstServlet extends HttpServlet {
  3.   public void doGet(HttpServletRequest request, HttpServletResponse response){
  4.     System.out.println("First Servlet........");
  5.    }
  6. }
复制代码
2.启动类扫描web组件
  1. @SpringBootApplication
  2. //SpringBoot启动时扫描注册注解标注的Web组件
  3. @ServletComponentScan
  4. public class Springbootdemo2Application {
  5.   public static void main(String[] args) {
  6.     SpringApplication.run(Springbootdemo2Application.class, args);
  7.    }
  8. }
复制代码
注册方式二

编写servlet
  1. public class SecondServlet extends HttpServlet {
  2.   public void doGet(HttpServletRequest request, HttpServletResponse response){
  3.     System.out.println("Second Servlet........");
  4.    }
  5. }
复制代码
使用配置类注册servlet
  1. @Configuration
  2. public class ServletConfig {
  3.   //ServletRegistrationBean可以注册Servlet组件,将其放入Spring容器中即可注册Servlet
  4.   @Bean
  5.   public ServletRegistrationBean getServletRegistrationBean(){
  6.     // 注册Servlet组件
  7.     ServletRegistrationBean bean = new ServletRegistrationBean(new SecondServlet());
  8.     // 添加Servlet组件访问路径
  9.     bean.addUrlMappings("/second");
  10.     return bean;
  11.    }
  12. }
复制代码
SpringBoot整合Web开发_Filter

注册方式一

编写filter
  1. @WebFilter(urlPatterns = "/first")
  2. public class FirstFilter implements Filter {
  3.   @Override
  4.   public void init(FilterConfig filterConfig) throws ServletException { }
  5.   @Override
  6.   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  7.     System.out.println("进入First Filter");
  8.     filterChain.doFilter(servletRequest,servletResponse);
  9.     System.out.println("离开First Filter");
  10.    }
  11.   @Override
  12.   public void destroy() { }
  13. }
复制代码
启动类扫描web组件
  1. @SpringBootApplication
  2. //SpringBoot启动时扫描注册注解标注的Web组件
  3. @ServletComponentScan
  4. public class Springbootdemo2Application {
  5.   public static void main(String[] args) {
  6.     SpringApplication.run(Springbootdemo2Application.class, args);
  7.    }
  8. }
复制代码
注册方式二

编写filter
  1. public class SecondFilter implements Filter {
  2.   @Override
  3.   public void init(FilterConfig filterConfig) throws ServletException { }
  4.   
  5.   @Override
  6.   public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
  7.     System.out.println("进入Second Filter");
  8.     filterChain.doFilter(servletRequest,servletResponse);
  9.     System.out.println("离开Second Filter");
  10.    }
  11.   @Override
  12.   public void destroy() { }
  13. }
复制代码
使用配置类注册filter
  1. @Configuration
  2. public class FilterConfig {
  3.   @Bean
  4.   public FilterRegistrationBean getFilterRegistrationBean(){
  5.     // 注册filter组件
  6.     FilterRegistrationBean bean = new FilterRegistrationBean(new SecondFilter());
  7.     // 添加过滤路径
  8.     bean.addUrlPatterns("/second");
  9.     return bean;
  10.    }
  11. }
复制代码
SpringBoot整合Web开发_Listener

注册方式一

编写Listener
  1. @WebListener
  2. public class FirstListener implements ServletContextListener {
  3.   @Override
  4.   public void contextInitialized(ServletContextEvent sce) {
  5.     System.out.println("First Listener Init......");
  6.    }
  7.   @Override
  8.   public void contextDestroyed(ServletContextEvent sce) {
  9.    }
  10. }
复制代码
启动类扫描web组件
  1. @SpringBootApplication
  2. //SpringBoot启动时扫描注册注解标注的Web组件
  3. @ServletComponentScan
  4. public class Springbootdemo2Application {
  5.   public static void main(String[] args) {            
  6.     SpringApplication.run(Springbootdemo2Application.class, args);
  7.    }
  8. }
复制代码
注册方式二

编写Listener
  1. public class SecondListener implements ServletContextListener {
  2.   @Override
  3.   public void contextInitialized(ServletContextEvent sce) {
  4.     System.out.println("Second Listener Init......");
  5.    }
  6.   @Override
  7.   public void contextDestroyed(ServletContextEvent sce) {
  8.    }
  9. }
复制代码
使用配置类注册Listener
  1. @Configuration
  2. public class ListenerConfig {
  3.   @Bean
  4.   public ServletListenerRegistrationBean getServletListenerRegistrationBean(){
  5.     ServletListenerRegistrationBean bean = new ServletListenerRegistrationBean(new SecondListener());
  6.     return bean;
  7.    }
  8. }
复制代码
SpringBoot整合Web开发_静态资源

SpringBoot项目中没有WebApp目录,只有src目录。在src/main/resources下面有static和templates两个文件夹。SpringBoot默认在static目录中存放静态资源,而在templates中放动态页面。
   SpringBoot不推荐JSP作为动态页面,推荐使用Thymeleaf技术编写动态页面。templates目录是存放Thymeleaf页面的目录,稍后我们讲解Thymeleaf技术。
  接下来我们在resources/static中编写html静态页面:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <title>测试HTML</title>
  6.   <script src="/js/page1.js"></script>
  7.   <link rel="stylesheet" href="/css/page1.css" />
  8. </head>
  9. <body>
  10. <p>我的HTML</p>
  11. <img src="/img/img.png">
  12. </body>
  13. </html>
复制代码
目录结构

SpringBoot整合Web开发_静态资源其他存放位置

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


  • /resources/META‐INF/resources/
  • /resources/resources/
  • /resources/public/

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

在SpringBoot配置文件进行自定义静态资源位置配置
  1. spring:
  2.   web:
  3.    resources:
  4.     static-locations: classpath:/suibian/,classpath:/static/
复制代码
  注意
该配置会覆盖默认静态资源位置,如果还想使用之前的静态资源位置,还需要配置在后面。
SpringBoot2.5之前的配置方式为:spring.resources.static-locations
  SpringBoot整合Web开发_JSP

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


  • 由于SpringBoot自带tomcat无法解析JSP,需要在pom文件添加JSP引擎
  1. <!--添加jsp引擎,SpringBoot内置的Tomcat不能解析JSP-->
  2. <dependency>
  3.   <groupId>org.apache.tomcat.embed</groupId>
  4.   <artifactId>tomcat-embed-jasper</artifactId>
  5. </dependency>
复制代码


  • 将webapp标志为web目录

  • 创建webapp目录,编写JSP文件

  1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
  2. <html>
  3. <head>
  4.   <title>MYJSP</title>
  5. </head>
  6. <body>
  7. MYJSP
  8. </body>
  9. </html>
复制代码


  • 启动项目,访问http://localhost:8080/myJsp.jsp
SpringBoot整合MyBatis

Spring整合MyBatis时需要进行大量配置,而SpringBoot整合MyBatis则可以简化很多配置:
1.准备数据库
  1. CREATE DATABASE `student`;
  2. USE `student`;
  3. DROP TABLE IF EXISTS `student`;
  4. CREATE TABLE `student` (
  5. `id` int(11) NOT NULL AUTO_INCREMENT,
  6. `name` varchar(255) DEFAULT NULL,
  7. `sex` varchar(10) DEFAULT NULL,
  8. `address` varchar(255) DEFAULT NULL,
  9. PRIMARY KEY (`id`)
  10. ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
  11. insert into `student`(`id`,`name`,`sex`,`address`) values (1,'百战程序员','男','北京'),(2,'北京尚学堂','女','北京');
复制代码
2.在pom中添加MyBatis起步依赖和Mysql驱动依赖
  1. <dependencies>
  2.   <dependency>
  3.     <groupId>org.springframework.boot</groupId>
  4.     <artifactId>spring-boot-starter-web</artifactId>
  5.   </dependency>
  6.   <!-- mybatis起步依赖 -->
  7.   <dependency>
  8.     <groupId>org.mybatis.spring.boot</groupId>
  9.     <artifactId>mybatis-spring-boot-starter</artifactId>
  10.     <version>3.0.2</version>
  11.   </dependency>
  12.   <!-- mysql依赖 -->
  13.   <dependency>
  14.     <groupId>com.mysql</groupId>
  15.     <artifactId>mysql-connector-j</artifactId>
  16.     <scope>runtime</scope>
  17.   </dependency>
  18.   <dependency>
  19.     <groupId>org.springframework.boot</groupId>
  20.     <artifactId>spring-boot-starter-test</artifactId>
  21.     <scope>test</scope>
  22.   </dependency>
  23.   <!-- mybatis测试起步依赖 -->
  24.   <dependency>
  25.     <groupId>org.mybatis.spring.boot</groupId>
  26.     <artifactId>mybatis-spring-boot-starter-test</artifactId>
  27.     <version>3.0.2</version>
  28.     <scope>test</scope>
  29.   </dependency>
  30. </dependencies>
复制代码
3.编写实体类
  1. public class Student {
  2.   private int id;
  3.   private String name;
  4.   private String sex;
  5.   private String address;
  6.   
  7.   // 省略构造方法/getter/setter/tostring
  8. }
复制代码
4.编写Mapper
  1. @Mapper
  2. public interface StudentMapper {
  3.   List<Student> findAll();
  4.   
  5.   @Select("select * from student where id = #{id}")
  6.   Student findById(int id);
  7. }
复制代码
5.编写Mapper映射文件
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3.     PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.     "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.jjy.springbootmybatis.mapper.StudentMapper">
  6.   <select id="findAll" resultType="student">
  7.      select * from student
  8.   </select>
  9. </mapper>
复制代码
6.编写配置文件
  1. # 配置数据源
  2. spring:
  3.   datasource:
  4.    driver-class-name: com.mysql.cj.jdbc.Driver
  5.    url: jdbc:mysql:///student?serverTimezone=UTC
  6.    username: root
  7.    password: root
  8. #mybatis配置
  9. mybatis:
  10. # 映射文件位置
  11.   mapper-locations: com/jjy/springbootdemo7/mapper/*Mapper.xml
  12. # 别名
  13.   type-aliases-package: com.jjy.springbootdemo7.pojo
  14. logging:
  15.   pattern:
  16.    console: '%d{HH:mm:ss.SSS} %clr(%-5level) ---  [%-15thread] %cyan(%-50logger{50}):%msg%n'
复制代码
SpringBoot单元测试

写了MyBatis相关代码后,我们要测试MyBatis代码是否正确。需要进行单元测试。SpringBoot单元测试要比Spring更简朴。
1.SpringBoot项目在构建时,默认引入单元测试的起步依赖
  1. <dependency>
  2.   <groupId>org.springframework.boot</groupId>
  3.   <artifactId>spring-boot-starter-test</artifactId>
  4.   <scope>test</scope>
  5. </dependency>
复制代码
2.在src.test.java下创建测试类,也可以让idea主动创建测试类,打开要测试的类:
ctrl+shift+t --> create new test

3.编写测试类
  1. // 测试类注解,可以在运行测试代码时加载容器
  2. @SpringBootTest
  3. class StudentMapperTest {
  4.   @Autowired
  5.   private StudentMapper studentMapper;
  6.   @Test
  7.   void findAll() {
  8.     List<Student> all = studentMapper.findAll();
  9.     all.forEach(System.out::println);
  10.    }
  11.   @Test
  12.   void findById() {
  13.     Student student = studentMapper.findById(1);
  14.     System.out.println(student);
  15.    }
  16. }
复制代码
SpringBoot热部署

热部署,就是在应用正在运行的时候升级软件,却不需要重新启动应用。即修改完代码后不需要重启项目即可生效。在SpringBoot中,可以使用DevTools工具实现热部署
1.添加DevTools依赖
  1. <!-- 热部署工具 -->
  2. <dependency>
  3.   <groupId>org.springframework.boot</groupId>
  4.   <artifactId>spring-boot-devtools</artifactId>
  5.   <optional>true</optional>
  6. </dependency>
复制代码

  • 在idea中设置主动编译
点击File–>Settings–>Compiler

3.开启答应在运行中修改文件
点击File–>Settings–>Advanced Settings,勾选Allow auto-make to start even if developed application is currently running

此时热部署即可生效
SpringBoot定时任务

定时任务即系统在特定时间实行一段代码。Spring Boot默认已经整合了Spring Task定时任务,只需要添加相应的注解即可完成。
1.在启动类中加入@EnableScheduling注解即可开启定时任务
  1. @SpringBootApplication
  2. @EnableScheduling
  3. public class Demo1Application {
  4.   public static void main(String[] args) {
  5.     SpringApplication.run(Demo1Application.class, args);
  6.    }
  7. }
复制代码
2.编写定时任务
  1. @Component
  2. public class MyTask {
  3.   // 定时任务方法,每秒执行一次
  4.   @Scheduled(cron="* * * * * *")
  5.   public void task1() {
  6.     SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
  7.     System.out.println(sdf.format(new Date()));
  8.    }
  9. }
复制代码
  @Scheduled 是 Spring Framework 中的一个注解,它用于标志一个方法,使其成为一个定时任务,按照肯定的时间间隔或特定的时间点实行。cron 参数是一个字符串,用于定义任务实行的筹划。Cron 表达式由六或七个字段组成,每个字段代表不同的时间单元:
秒 (0 - 59)
分钟 (0 - 59)
小时 (0 - 23,24小时制)
日期 (1 - 31)
月份 (1 - 12 或 JAN-DEC)
星期几 (0 - 7,7 或 0 表示星期天,大概使用 SUN-SAT)
年份(可选字段)
cron="* * * * * " 表示:
秒:
表示每秒钟都会触发一次。
分钟:* 表示每分钟的每秒钟都会触发。
小时:* 表示每小时的每分钟都会触发。
日期:* 表示每月的每天都会触发。
月份:* 表示每年的每个月都会触发。
星期几:* 表示每周的每一天都会触发。
这意味着任务将每秒钟实行一次,这通常是不必要的,除非有特定的需求需要如此高频率的实行。通常,我们会根据实际需要来调解这个表达式,以克制过度实行任务。
  3.启动项目,定时任务方法按照配置定时实行。
SpringBoot内容协商机制


如果我们的Java服务为欣赏器和安卓手机同时提供服务,欣赏器盼望接受的哀求是JSON格式,安卓客户端盼望吸取的哀求是XML格式,这个时候是否需要写两个方法?
不需要!SpringBoot的内容协商机制可以解决这个问题。
内容协商机制:根据客户端吸取本领不同,SpringBoot 返回不同媒体类型的数据。
Spring默认支持内容协商机制,但SpringBoot默认只支持返回Json数据,所以需要导入jackson-dataformat-xml让SpringBoot支持返回xml数据
1.引入依赖
  1. <!-- 引入支持返回 xml 数据格式 -->
  2. <dependency>
  3.   <groupId>com.fasterxml.jackson.dataformat</groupId>
  4.   <artifactId>jackson-dataformat-xml</artifactId>
  5. </dependency>
复制代码
2.编写控制器
  1. @Controller
  2. public class ConsultController {
  3.   @Autowired
  4.   private StudentMapper studentMapper;
  5.   @RequestMapping("/student/findById")
  6.   @ResponseBody
  7.   public Student findById(Integer id){
  8.     Student student = studentMapper.findById(id);
  9.     return student;
  10.    }
  11. }
复制代码
3.进行测试,SpringBoot的内容协商机制是根据哀求头不同,返回不同格式的数据,所以需要我们能够修改哀求头,我们使用postman进行测试:


SpringBoot内容协商机制_基于哀求参数

SpringBoot默认根据哀求头不同,返回不同的数据格式。我们还可以配置基于哀求参数的内容协商,也就是哀求参数值不同,返回不同的数据:
1.配置SpringBoot基于哀求参数的内容协商
  1. #开启请求参数内容协商模式
  2. spring.mvc.contentnegotiation.favor-parameter=true
  3. #请求参数内容协商模式的参数名
  4. spring.mvc.contentnegotiation.parameter-name=format
复制代码
2.在postman进行测试:


SpringBoot国际化

国际化:(Internationalization 简称 I18n,其中“I”和“n”分别为首末字符,18 则为中间的字符数)。是指软件能同时应对不同国家和地域的用户访问,并根据用户地域和语言风俗,提供相应的、符合用具阅读风俗的页面和数据,例如,为中国用户提供汉语界面表现,为美国用户提供英语界面表现。接下来我们来说一下在SpringBoot项目中,如何进行国际化配置:
1、编写国际化资源文件
SpringBoot国际化资源文件的文件名规范为:基本名_语言代码_国家或地域代码。例如:


  • 美国英语:messages_en_US.properties:
  • 中国汉语:messages_zh_CN.properties。
    我们在 src/main/resources中,按照国际化资源文件定名格式分别创建以下三个文件:
  • messages.properties:无语言设置时生效
  • messages_en_US.properties:美国英语时生效
  • messages_zh_CN.properties:中文时生效

编写三个文件:
  1. # messages.properties
  2. welcome=欢迎使用{0}(默认)
  3. # messages_en_US.properties
  4. welcome=welcome to {0}
  5. # messages_zh_CN.properties
  6. welcome=欢迎使用{0}(中文)
复制代码
  注意,这里要将项目配置文件的编码方式改成UTF-8,否则会出现乱码
  

2、在配置文件指定国际资源文件的基本名
  1. spring:
  2.   messages:
  3.    basename: messages
复制代码
3、编写控制器
  1. @Controller
  2. public class I18nController {
  3.   @Autowired
  4.   private MessageSource messageSource;
  5.   @RequestMapping("/welcome")
  6.   @ResponseBody
  7.   public String welcome(HttpServletRequest request) {
  8.     // 获取请求来源的地区
  9.     Locale locale = request.getLocale();
  10.     /**
  11.      * 使用国际化
  12.      * 第一个参数是国际化文件的key,
  13.      * 第二个参数value中的占位符数据
  14.      * 第三个是区域
  15.      */
  16.     String welcome = messageSource.getMessage("welcome", new Object[]{"springboot"}, locale);
  17.     return welcome;
  18.    }
  19. }
复制代码
4、在欣赏器测试国际化
先在默认情况下访问/welcome,之后切换欣赏器环境,再次访问/welcome

SpringBoot国际化_在Thymeleaf中进行国际化

在Thymeleaf页面中获取国际化资源数据的方式如下:
  1. <!DOCTYPE html>
  2. <html xmlns:th="http://www.thymeleaf.org">
  3. <head>
  4.   <meta charset="UTF-8"/>
  5.   <title>Title</title>
  6. </head>
  7. <body>
  8. <h1 th:text="#{welcome('springboot')}">欢迎</h1>
  9. <h1>[[#{welcome('springboot')}]]</h1>
  10. </body>
  11. </html>
复制代码
SpringBoot参数校验

简朴数据类型

SpringBoot自带了validation工具可以从后端对前端传来的参数进行校验,用法如下:
1.引入validation起步依赖
  1. <!-- 参数校验 -->
  2. <dependency>
  3.   <groupId>org.springframework.boot</groupId>
  4.   <artifactId>spring-boot-starter-validation</artifactId>
  5. </dependency>
复制代码
2.编写Controller
  1. // 该控制器开启参数校验
  2. @Validated
  3. @Controller
  4. public class TestController {
  5.   @RequestMapping("/t1")
  6.   @ResponseBody
  7.   // 在参数前加校验注解,该注解的意思是字符串参数不能为null
  8.   public String t1(@NotBlank String username){
  9.     System.out.println(username);
  10.     return "请求成功!";
  11.    }
  12. }
复制代码
3.访问http://localhost:8080/t1,发现当没有传来参数时,会抛出ConstraintViolationException异常。
4.在校验参数的注解中添加message属性,可以更换异常信息。
  1. // 该控制器开启参数校验
  2. @Validated
  3. @Controller
  4. public class TestController {
  5.   @RequestMapping("/t1")
  6.   @ResponseBody
  7.   // 在参数前加校验注解,该注解的意思是字符串参数不能为null
  8.   public String t1(@NotBlank(message = "用户名不能为空") String username){
  9.     System.out.println(username);
  10.     return "请求成功!";
  11.    }
  12. }
复制代码
异常处理

当抛出ConstraintViolationException异常后,我们可以使用SpringMVC的异常处理器,也可以使用SpringBoot自带的异常处理机制。
当步伐出现了异常,SpringBoot会使用自带的BasicErrorController对象处理异常。该处理器会默认跳转到/resources/templates/error.html页面。
编写异常页面:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <title>错误页面</title>
  6. </head>
  7. <body>
  8. <h1>服务器开小差了!</h1>
  9. </body>
  10. </html>
复制代码
参数校验_校验相关注解

注解作用@NotNull判定包装类是否为null@NotBlank判定字符串是否为null大概是空串(去掉首尾空格)@NotEmpty判定聚集是否为空@Length判定字符的长度(最大大概最小)@Min判定数值最小值@Max判定数值最大值@Email判定邮箱是否合法
  1. @RequestMapping("/t2")
  2. @ResponseBody
  3. public String t2(
  4.     @NotBlank @Length(min = 1, max = 5) String username,
  5.     @NotNull @Min(0) @Max(150) Integer age,
  6.     @NotEmpty @RequestParam List<String> address,
  7.     @NotBlank @Email String email) {
  8.   System.out.println(username);
  9.   System.out.println(age);
  10.   System.out.println(address);
  11.   System.out.println(email);
  12.   return "请求成功!";
  13. }
复制代码
参数校验_对象类型

SpringBoot也可以校验对象参数中的每个属性,用法如下:
1.添加实体类
  1. public class Student {
  2.   @NotNull(message = "id不能为空")
  3.   private Integer id;
  4.   @NotBlank(message = "姓名不能为空")
  5.   private String name;
  6.   // 省略getter/setter/tostring
  7. }
复制代码
2.编写控制器
  1. @Controller
  2. public class TestController2 {
  3.   @RequestMapping("/t3")
  4.   @ResponseBody
  5.   // 校验的对象参数前添加@Validated,并将异常信息封装到BindingResult对象中
  6.   public String t3(@Validated Student student,BindingResult result) {
  7.     // 判断是否有参数异常
  8.     if (result.hasErrors()) {
  9.       // 所有参数异常
  10.       List<ObjectError> list = result.getAllErrors();
  11.       // 遍历参数异常,输出异常信息
  12.       for (ObjectError err : list) {
  13.         FieldError fieldError = (FieldError) err;
  14.         System.out.println(fieldError.getDefaultMessage());
  15.        }
  16.       return "参数异常";
  17.      }
  18.     System.out.println(student);
  19.     return "请求成功!";
  20.    }
  21. }
复制代码
SpringBoot指标监控

添加Actuator功能

Spring Boot Actuator可以资助步伐员监控和管理SpringBoot应用,好比健康查抄、内存使用情况统计、线程使用情况统计等。我们在SpringBoot项目中添加Actuator功能,即可使用Actuator监控项目,用法如下:
1.在被监控的项目中添加Actuator起步依赖
  1. <dependency>
  2.   <groupId>org.springframework.boot</groupId>
  3.   <artifactId>spring-boot-starter-actuator</artifactId>
  4. </dependency>
复制代码
2.编写配置文件
  1. #开启所有监控端点
  2. management:
  3.   endpoints:
  4.    web:
  5.     exposure:
  6.      include: '*'
  7.      
复制代码
3.访问项目:http://localhost:8080/actuator
通过URL可以调用actuator的功能:
URL查看的数据/env环境属性/health健康查抄/mappings表现全部的@RequestMapping路径/loggers日志/info定制信息/metrics查看内存、CPU核心等系统参数/trace用户哀求信息 例如查询健康数据,访问http://localhost:8080/actuator/health
Spring Boot Admin


Actuator使用JSON格式展示了大量指标数据,倒霉于我们查看,我们可以使用可视化工具Spring Boot Admin查看actuator生成指标数据。Spring Boot Admin是一个独立的项目,我们需要创建并运行该项目。
创建Spring Boot Admin服务端项目
1.创建SpringBoot项目,添加SpringMVC和Spring Boot Admin服务端起步依赖
  1. <dependency>
  2.   <groupId>org.springframework.boot</groupId>
  3.   <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <dependency>
  6.   <groupId>de.codecentric</groupId>
  7.   <artifactId>spring-boot-admin-starter-server</artifactId>
  8.   <version>3.1.3</version>
  9. </dependency>
复制代码
2.修改配置文件
  1. # 端口号
  2. server.port=9090
  3. # 日志格式
  4. logging.pattern.console=%d{HH:mm:ss.SSS} %clr(%-5level) ---  [%-15thread] %cyan(%-50logger{50}):%msg%n
复制代码
3.修改启动类
  1. @SpringBootApplication
  2. @EnableAdminServer //开启Spring Boot Admin服务端
  3. public class MyadminApplication {
  4.   public static void main(String[] args) {
  5.     SpringApplication.run(MyadminApplication.class, args);
  6.    }
  7. }
复制代码
连接Spring Boot Admin项目
在被监控的项目中连接Spring Boot Admin项目,才能使用Spring Boot Admin查看指标数据。
被监控项目添加Spring Boot Admin客户端起步依赖
  1. <dependency>
  2.   <groupId>de.codecentric</groupId>
  3.   <artifactId>spring-boot-admin-starter-client</artifactId>
  4.   <version>3.1.3</version>
  5. </dependency>
复制代码
修改配置文件
  1. #Spring boot admin访问地址
  2. spring.boot.admin.client.url=http://localhost:9090
复制代码
此时Spring Boot Admin即可连接被监控的项目
SpringBoot日志管理

Logback

SpringBoot默认使用Logback组件作为日志管理。Logback是log4j创始人设计的一个开源日志组件。在SpringBoot中已经整合了Logback的依赖,所以我们不需要额外的添加其他依赖:
Logback配置用法如下:
1.在/resources下添加Logback配置文件logback.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <configuration>
  3.   <!--定义日志文件的存储地址-->
  4.   <property name="LOG_HOME" value="${catalina.base}/logs/"/>
  5.   
  6.   <!-- 控制台输出 -->
  7.   <appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
  8.     <!-- 日志输出编码 -->
  9.     <layout class="ch.qos.logback.classic.PatternLayout">
  10.       <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
  11.       <pattern>%d{MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
  12.       </pattern>
  13.     </layout>
  14.   </appender>
  15.   
  16.   <!-- 按照每天生成日志文件 -->
  17.   <appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
  18.     <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  19.       <!--日志文件输出的文件名-->
  20.       <FileNamePattern>${LOG_HOME}/server.%d{yy99-MM-dd}.log</FileNamePattern>
  21.       <MaxHistory>30</MaxHistory>
  22.     </rollingPolicy>
  23.     <layout class="ch.qos.logback.classic.PatternLayout">
  24.       <!--格式化输出:%d表示时间,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
  25.       <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
  26.       </pattern>
  27.     </layout>
  28.     <!--日志文件最大的大小-->
  29.     <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
  30.       <MaxFileSize>10MB</MaxFileSize>
  31.     </triggeringPolicy>
  32.   </appender>
  33.   <!-- 日志输出级别 -->
  34.   <root level="info">
  35.     <appender-ref ref="Stdout"/>
  36.     <appender-ref ref="RollingFile"/>
  37.   </root>
  38. </configuration>
复制代码
  注:Logback配置文件名为logback-test.xml或logback.xml,如果classpath下没有这两个文件,LogBack会主动进行最小化配置。
  打印自定义日志

如果想在运行时打印自定义日志,只需要引入Logger对象即可:
  1. @Controller
  2. public class LogbackController {
  3.   private final static Logger logger = LoggerFactory.getLogger(LogbackController.class);
  4.   @RequestMapping("/printLog")
  5.   @ResponseBody
  6.   public String showInfo(){
  7.     logger.info("记录日志");
  8.     return "Hello Logback";
  9.    }
  10. }
复制代码
如果日志过多,可以屏蔽一些包的日志,在配置文件中配置
  1. #屏蔽org包中的日志输出
  2. logging.level.org=off
复制代码
SpringBoot项目部署

项目打包

SpringBoot项目是依赖于Maven构建的,但打包时如果只依赖Maven打包工具则会打包不完整,我们还需要在SpringBoot项目中引入SpringBoot打包插件 :
  1. <build>
  2.   <plugins>
  3.     <plugin>
  4.       <groupId>org.springframework.boot</groupId>
  5.       <artifactId>spring-boot-maven-plugin</artifactId>
  6.     </plugin>
  7.   </plugins>
  8. </build>
复制代码
此时再使用Maven插件打包:

运行jar包:
1.进入jar包所在目录,使用cmd打开命令行窗口
2.输入命令:
   java -jar jar包名
  多环境配置

在真实开发中,在不同环境下运行项目往往会进行不同的配置,好比开发环境使用的是开发数据库,测试环境使用的是测试数据库,生产环境使用的是生产数据库。SpringBoot支持不同环境下使用不同的配置文件,用法如下:
配置文件名:
application-环境名.properties/yml
如:
application-dev.properties/yml 开发环境配置文件
  1. # 开发环境端口号为8080
  2. server:
  3.   port: 8080
复制代码
application-test.properties/yml 测试环境配置文件
  1. # 测试环境端口号为8081
  2. server:
  3.   port: 8081
复制代码
application-prod.properties/yml 生产环境配置文件
  1. # 生产环境端口号为80
  2. server:
  3.   port: 80
复制代码
运行jar包时选择环境:
  1. java -jar jar包名 --spring.profiles.active=环境名
复制代码
Dockerfile制作镜像

为了节约资源,在生产环境中我们更多的是使用Docker容器部署SpringBoot应用,首先我们准备Docker环境:
1.准备一台centos7系统的假造机,连接假造机。
2.关闭假造机防火墙
  1. # 关闭运行的防火墙
  2. systemctl stop firewalld.service
  3. # 禁止防火墙自启动
  4. systemctl disable firewalld.service
复制代码
3.安装Docker
  1. # 安装Docker
  2. yum -y install docker
  3. # 启动docker
  4. systemctl start docker
复制代码
4.由于SpringBoot中嵌入了Web容器,所以在制作SpringBoot项目的镜像时无需依赖Web容器,基于JDK制作镜像即可,接下来我们使用Dockerfile制作镜像:
5.进入opt目录
  1. cd /opt
复制代码
6.使用rz命令将项目Jar包上传至假造机
7.编写DockerFile
  1. cat <<EOF > Dockerfile
  2. # 基于JDK17
  3. FROM openjdk:17
  4. # 作者
  5. MAINTAINER itbaizhan
  6. # 拷贝到容器opt目录
  7. ADD springbootdemo9-0.0.1-SNAPSHOT.jar /opt
  8. #保留端口
  9. EXPOSE 8080
  10. # 启动容器后执行的命令
  11. CMD java -jar /opt/springbootdemo9-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
  12. EOF
复制代码
8.构建镜像
  1. docker build -t springbootdocker .
复制代码
9.查看全部的镜像,出现springbootdocker代表镜像构建成功
  1. docker images
复制代码
10.使用镜像启动容器
  1. docker run -d -p 8080:8080 springbootdocker
复制代码
11.访问项目
Maven插件制作镜像

除了DockerFile,我们还可以使用Maven插件制作镜像。使用方法如下:
1.开启远程docker服务
  1. # 修改docker配置文件
  2. vim /lib/systemd/system/docker.service
  3. # 在ExecStart=后添加配置,远程访问docker的端口为2375
  4. ExecStart=/usr/bin/dockerd-current -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \
  5.      --add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
  6.      --default-runtime=docker-runc \
  7.      --exec-opt native.cgroupdriver=systemd \
  8.      --userland-proxy-path=/usr/libexec/docker/docker-proxy-current \
  9.      --init-path=/usr/libexec/docker/docker-init-current \
  10.      --seccomp-profile=/etc/docker/seccomp.json \
  11.      $OPTIONS \
  12.      $DOCKER_STORAGE_OPTIONS \
  13.      $DOCKER_NETWORK_OPTIONS \
  14.      $ADD_REGISTRY \
  15.      $BLOCK_REGISTRY \
  16.      $INSECURE_REGISTRY \
  17.      $REGISTRIES
  18. # 重启docker
  19. systemctl daemon-reload
  20. systemctl restart docker
复制代码
2.在项目的pom文件中添加docker-maven-plugin插件
  1. <!-- docker-maven-plugin-->
  2. <plugin>
  3.   <groupId>com.spotify</groupId>
  4.   <artifactId>docker-maven-plugin</artifactId>
  5.   <version>1.2.2</version>
  6.   <configuration>
  7.     <!-- Docker路径 -->
  8.     <dockerHost>http://192.168.1.25:2375</dockerHost>
  9.     <!-- Dockerfile定义 -->
  10.     <baseImage>openjdk:17</baseImage>
  11.     <!-- 作者 -->
  12.     <maintainer>itbaizhan</maintainer>
  13.     <resources>
  14.       <resource>
  15.         <!-- 复制jar包到docker容器指定目录 -->
  16.         <targetPath>/</targetPath>
  17.         <!-- 从哪个包拷贝文件,target包 -->
  18.         <directory>${project.build.directory}</directory>
  19.         <!-- 拷贝哪个文件 -->
  20.         <include>${project.build.finalName}.jar</include>
  21.       </resource>
  22.     </resources>
  23.     <workdir>/</workdir>
  24.     <entryPoint>["java", "-jar", "${project.build.finalName}.jar","--spring.profiles.active=dev"]</entryPoint>
  25.     <forceTags>true</forceTags>
  26.     <!-- 镜像名 -->
  27.     <imageName>${project.artifactId}</imageName>
  28.     <!-- 镜像版本 -->
  29.     <imageTags>
  30.       <imageTag>${project.version}</imageTag>
  31.     </imageTags>
  32.   </configuration>
  33. </plugin>
复制代码
3.使用maven的package命令给项目打包

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

5.查看镜像是否构建成功
  1. docker images
复制代码
6.使用镜像启动容器
  1. docker run -d -p 8081:8080 demo1:0.0.1-SNAPSHOT
复制代码
7.访问项目
SpringBoot3新特性

与之前版本的改动

我们在使用SpringBoot3的时候,肯定要注意以下几个方面的改动:


  • JDK要求最低版本Java17
  • SpringBoot3底层默认的Spring版本是Spring6
  • 新增了一些起步依赖,有一些起步依赖进行了调解,但改动不大。
  • 主动配置包位置发生了变化
SpringBoot2.x

SpringBoot3.x



  • jakarta api迁移
由于JavaEE已经变动为Jakarta EE,包名以 javax开头的需要相应地变动为jakarta
SpringBoot2.x

SpringBoot3.x

ProblemDetails

RFC 7807
之前的项目如果出现异常,默认跳转到error页面。大概是抛出500异常。


但是对于前后端分离的项目,Java步伐员不负责页面跳转,只需要把错误信息交给前端步伐员处理即可。而RFC 7807规范就是将异常信息转为JSON格式的数据。这个JSON数据包含五个部分


  • type: 问题形貌文档所在,如果不存在,则"about:blank"
  • title: 简短的形貌问题
  • status: http 状态码,好比400、401、500等
  • detail: 详细阐明发生问题的原因
  • instance: 问题发生的URL所在
  1. {
  2.   "type": "https://pack.com/probs/out-of-credit",
  3.   "title": "你没有足够的信用。",
  4.   "status": 601,
  5.   "detail": "你现在的余额是30,但是要花50。",
  6.   "instance": "/account/12345/msgs/abc"
  7. }
复制代码
前端步伐员拿到这串JSON数据进行处理就可以了。
ProblemDetails
SpringBoot中提供了一个类ProblemDetailsExceptionHandler,他会把错误信息转为RFC 7807规范并返回。
可以看到ProblemDetailsExceptionHandler是一个异常处理器

它会处理以下异常

接下来我们就使用ProblemDetails处理异常,哀求方式异常也属于ProblemDetails处理的异常,我们就模拟改异常的发生。
ProblemDetails默认是不开启的,要想开启需要进行如下配置:
  1. spring.mvc.problemdetails.enabled=true
复制代码
编写一个控制器方法
  1. @Controller
  2. public class ProblemDetailsController {
  3.   @GetMapping("/testProblem")
  4.   @ResponseBody
  5.   public String testProblem(){
  6.     return "hello";
  7.    }
  8. }
复制代码
用POST方式访问该方法:

原生镜像

JAVA语言的实行原理


  • 计算机语言:
    计算机能够直接实行的指令。这种指令和系统及硬件有关。
  • 计算机高级语言:
    在遵循语法的条件下,写一个文本文件,之后使用某种方式,把文本转换为计算机指令实行。
我们编写的都是计算机高级语言,而将计算机高级语言转为计算机语言运行,有两种方式:


  • 动态解释(JIT):解释实行,运行时翻译为机器码。(好比Python,也称为解释型语言)

  • 静态编译(AOT):步伐在实行前全部被翻译为机器码,可以直接运行二进制文件。(好比C++,也称为解释型语言)

    这两种方式各有优缺点,动态解释代码运行效率较低,但可以跨平台运行。
静态编译代码运行效率较高,但不能跨平台运行,而且编译代码比较浪费时间,调试成本高。
JAVA语言:先编译,后解释实行

   注意,JVM并不是单纯依赖解释器解释假造指令,JVM中既有解释器,还有即时编译器。
  

  • 解释器可以将字节码文件解释为机器指令,立即实行。
  • 即时编译器可以将字节码文件编译为机器指令,存在内存中,编译完成后直接实行本地机器指令即可。
    当Java假造器启动后,解释器首先发挥作用,不必期待即时编译器全部编译完成后再实行。随着时间的推移,编译器把越来越多的代码编译成本地代码,此时运行本地机器指令,获得更高的实行效率。
  固然这种启动方式很良好,但他的启动照旧比AOT方式慢。在当前微服务云原生盛行的时代,JAVA 步伐显得越来越痴肥,固然使用AOT也有诸多缺点,好比打包时间长、舍弃平台无关性、反射、动态代理的分析本领有限。但是JAVA必定会向AOT发展,否则在云原生时代,可以能被其他后起之秀慢慢蚕食市场。
  Native Image 和 GraalVM

Native Image
Native Image(原生镜像)是一种将Java代码提前编译为二进制文件的技术,即本机可实行文件。在Windows中就是.exe文件,它脱离了Java步伐员运行时对JVM的依赖,运行时效率极高。
Spring推荐使用SpringBoot3+GraalVM官方构建工具实现原生镜像构建。
GraalVM
GraalVM是一个高性能跨语言假造机,其目的是提拔Java和其他使用JVM语言编写步伐的实行速度,同时也为JavaScript、Python和很多其他流行语言提供运行时环境。起始于2011年Oracle实验室的一个研究项目。

   GraalVM可以直接当做JVM使用,也可以对Java等多种语言实现静态编译,生成Java项目的原生镜像。
  生成原生镜像

接下来我们就生成SpringBoot3项目的原生镜像:
1.安装GraalVM


  • 解压windows版的GraalVM
  • 配置环境变量JAVA_HOME和Path
2.创建SpringBoot项目
创建时的JDK肯定要选择GraalVM

添加依赖时肯定要选择GraalVM

编写控制器
  1. @Controller
  2. public class HelloController {
  3.   @ResponseBody
  4.   @RequestMapping("/hello")
  5.   public String hello(){
  6.     return "Hello Native Image";
  7.    }
  8. }
复制代码
3.通过安装VisualStudio安装C++开发环境,固然GraalVM可以生成原生镜像,但底层是调用C++的方式生成的.exe可实行文件。


4.使用maven将SpringBoot项目打包成可实行文件

生成Linux原生镜像

1.准备Linux假造机,连接假造机
2.安装C++开发环境
  1. yum install -y gcc glibc-devel zlib-devel
复制代码
3.安装GraalVM
  1. # 创建空文件夹
  2. mkdir -p /usr/local/java
  3. # 进入文件夹
  4. cd /usr/local/java
  5. # 上传GraalVM到Linux虚拟机
  6. # 解压GraalVM
  7. tar -zxvf graalvm-jdk-17_linux-x64_bin.tar.gz
复制代码
4.配置GraalVM环境变量
  1. # 打开环境变量配置文件
  2. vim  /etc/profile
  3. # 添加如下内容
  4. export JAVA_HOME=/usr/local/java/graalvm-jdk-17.0.8+9.1
  5. export PATH=$PATH:$JAVA_HOME/bin
  6. # 使环境变量生效
  7. source /etc/profile
  8. # 查看Java版本
  9. java -version
复制代码
如果Java版本没有改动,卸载掉Linux系统自带的JDK即可:
  1. # 查看系统自带的Java
  2. rpm -qa|grep java
  3. # 卸载JAVA
  4. rpm -e --nodeps java版本
复制代码
5.安装Maven
  1. # 创建空文件夹
  2. mkdir -p /usr/local/maven
  3. # 进入文件夹
  4. cd /usr/local/maven
  5. # 上传Maven到Linux虚拟机
  6. # 解压Maven
  7. tar -xvf apache-maven-3.8.8-bin.tar.gz
复制代码
6.配置Maven环境变量
  1. # 打开环境变量配置文件
  2. vim  /etc/profile
  3. # 添加如下内容
  4. export M2_HOME=/usr/local/maven/apache-maven-3.8.8
  5. export PATH=$PATH:$M2_HOME/bin
  6. # 使环境变量生效
  7. source /etc/profile
  8. # 查看Maven版本
  9. mvn -version
复制代码
7.修改SpringBoot项目pom文件
  1. <!-- 添加如下内容,使maven给项目打包时生成原生镜像 -->
  2. <profiles>
  3.   <profile>
  4.     <id>native</id>
  5.     <properties>
  6.       <repackage.classifier>exec</repackage.classifier>
  7.       <native-buildtools.version>0.9.13</native-buildtools.version>
  8.     </properties>
  9.     <build>
  10.       <plugins>
  11.         <plugin>
  12.           <groupId>org.graalvm.buildtools</groupId>
  13.           <artifactId>native-maven-plugin</artifactId>
  14.           <extensions>true</extensions>
  15.           <executions>
  16.             <execution>
  17.               <id>build-native</id>
  18.               <phase>package</phase>
  19.               <goals>
  20.                 <goal>build</goal>
  21.               </goals>
  22.             </execution>
  23.           </executions>
  24.         </plugin>
  25.       </plugins>
  26.     </build>
  27.   </profile>
  28. </profiles>
复制代码
8.把项目压缩成zip文件
9.把项目的压缩文件上传到假造机上
10解压项目
  1. # 安装unzip
  2. yum install unzip
  3. # 解压项目
  4. upzip springbootdemo10.zip
复制代码
10.进入项目,实行mvn clean package -DskipTests -Pnative,生成原生镜像
如果我的内容对你有资助,请点赞,批评,收藏。创作不易,各人的支持就是我对峙下去的动力


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

忿忿的泥巴坨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表