参考资料
SpringBoot2.4.3 官方文档
学习 SpringBoot 最权威的资料当然还是官方文档了:Spring Boot Reference Documentation
The reference documentation consists of the following sections(参考文档由如下部分组成):
Legal | Legal information. |
---|---|
Documentation Overview | About the Documentation, Getting Help, First Steps, and more. |
Getting Started | Introducing Spring Boot, System Requirements, Servlet Containers, Installing Spring Boot, Developing Your First Spring Boot Application |
Using Spring Boot | Build Systems, Structuring Your Code, Configuration, Spring Beans and Dependency Injection, DevTools, and more. |
创建系统/工程,构建代码,配置,Spring Beans 和依赖注入,开发工具等等 | |
Spring Boot Features | Profiles 配置, Logging 日志, Security 安全, Caching 缓存, Spring Integration 集成, Testing 测试, and more. |
Spring Boot Actuator | Monitoring, Metrics, Auditing, and more. |
Deploying Spring Boot Applications | Deploying to the Cloud, Installing as a Unix application. |
Spring Boot CLI | Installing the CLI, Using the CLI, Configuring the CLI, and more. |
Build Tool Plugins | Maven Plugin, Gradle Plugin, Antlib, and more. |
“How-to” Guides | Application Development, Configuration, Embedded Servers, Data Access, and many more. |
The reference documentation has the following appendices:
Application Properties | Common application properties that can be used to configure your application. |
---|---|
Configuration Metadata | Metadata used to describe configuration properties. |
Auto-configuration Classes | Auto-configuration classes provided by Spring Boot. |
Test Auto-configuration Annotations | Test-autoconfiguration annotations used to test slices of your application. |
Executable Jars | Spring Boot’s executable jars, their launchers, and their format. |
Dependency Versions | Details of the dependencies that are managed by Spring Boot. |
【江南一点雨】
Bilibili 教程:https://space.bilibili.com/49484631/
SpringBoot 教程-案例代码
| code-samples | 对应的文章 |
| ————————– | ———————————————————————————————————————— | ——————————————————————————————– |
| spring-boot-starter-custom | 徒手撸一个 Spring Boot 中的 Starter ,解密自动化配置黑魔法! |
| api.js | Spring Boot + Vue 前后端分离开发,前端网络请求封装与配置 |
| javassm | 这一次,我连 web.xml 都不要了,纯 Java 搭建 SSM 环境 |
| properties | 是时候彻底搞清楚 Spring Boot 的配置文件 application.properties 了! |
| redis | Spring Boot 操作 Redis,三种方案全解析! |
| sessionshare | Spring Boot 一个依赖搞定 session 共享,没有比这更简单的方案了! |
| restful | Spring Boot 中 10 行代码构建 RESTful 风格应用 |
| shiro | Spring Boot 整合 Shiro ,两种方式全总结! |
| quartz | Spring Boot 中实现定时任务的两种方式! |
| ehcache | 另一种缓存,Spring Boot 整合 Ehcache |
| thymeleaf | 极简 Spring Boot 整合 Thymeleaf 页面模板 |
| exception | Spring Boot 中关于自定义异常处理的套路! |
| jdbctemplate | Spring Boot 数据持久化之 JdbcTemplate |
| jdbcmulti | Spring Boot 多数据源配置之 JdbcTemplate |
| mybatis | 最简单的 SpringBoot 整合 MyBatis 教程 |
| mybatismulti | 极简 Spring Boot 整合 MyBatis 多数据源 |
| jpa | 是时候了解下 Spring Boot 整合 Jpa 啦 |
| jpamulti | Spring Boot 整合 Jpa 多数据源 |
| jwt | 干货 | 一个案例学会 Spring Security 中使用 JWT! |
| security_json | SpringSecurity 登录使用 JSON 格式数据 |
| swagger2 | SpringBoot 整合 Swagger2,再也不用维护接口文档了! |
| cors | Spring Boot 中通过 CORS 解决跨域问题 |
| freemarker | Spring Boot 整合 Freemarker,50 多行配置是怎么省略掉的? |
| mail | Spring Boot 邮件发送的 5 种姿势! |
| docker | 一键部署 Spring Boot 到远程 Docker 容器,就是这么秀! |
| https | Spring Boot 支持 Https 有那么难吗? |
| jwt-demo | Spring Security 结合 Jwt 实现无状态登录 |
| docker-jib | 别用 Dockerfile 部署 Spring Boot 啦!松哥教你两步搞定! |
SpringBoot 四大核心
- 自动配置
- 起步依赖
- Actuator
- 命令行界面
【遇见狂神说】
Bilibili 教程:https://space.bilibili.com/95256449
KuangStudy:https://www.kuangstudy.com/course
博客园:https://www.cnblogs.com/hellokuangshen/tag/SpringBoot 系列/
【编程不良人】
学习资料下载:https://www.baizhiedu.xin/
Bilibili 教程:https://space.bilibili.com/352224540
【动力节点 PowerNode】
Bilibili 教程:https://space.bilibili.com/76542346
官网资料:http://www.bjpowernode.com/tutorial/
【Springmeng&王汉远】
Bilibili 教程-springmeng:https://space.bilibili.com/395452961/
Bilibili 教程-王汗远:https://space.bilibili.com/431642687/
【尚学堂】
Bilibili 教程:https://space.bilibili.com/392179313/
【扣丁狼】
Bilibili 教程:https://space.bilibili.com/320032672/
【C 语言中文网】
参考:http://c.biancheng.net/spring_boot/
SpringBoot 的前世今生
1、Spring 能做什么
1.1、Spring 的能力
1.2、Spring 的生态
https://spring.io/projects/spring-boot
覆盖了:
- web 开发
- 数据访问
- 安全控制
- 分布式
- 消息服务
- 移动开发
- 批处理
- ……
1.3、Spring5 重大升级
1.3.1、响应式编程
1.3.2、内部源码设计
基于 Java8 的一些新特性,如:接口默认实现。重新设计源码架构。
2、为什么用 SpringBoot
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
能快速创建出生产级别的 Spring 应用(简化开发)
2.1、SpringBoot 优点
- Create stand-alone Spring applications
- 创建独立 Spring 应用
- Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
- 内嵌 web 服务器
- Provide opinionated ‘starter’ dependencies to simplify your build configuration
- 自动 starter 依赖,简化构建配置
- Automatically configure Spring and 3rd party libraries whenever possible
- 自动配置 Spring 以及第三方功能
- Provide production-ready features such as metrics, health checks, and externalized configuration
- 提供生产级别的监控、健康检查及外部化配置
- Absolutely no code generation and no requirement for XML configuration
- 无代码生成、无需编写 XML
SpringBoot 是整合 Spring 技术栈的一站式框架
SpringBoot 是简化 Spring 技术栈的快速开发脚手架
- 无代码生成、无需编写 XML
2.2、SpringBoot 缺点
- 人称版本帝,迭代快,需要时刻关注变化
- 封装太深,内部原理复杂,不容易精通
3、时代背景
3.1、微服务
James Lewis and Martin Fowler (2014) 提出微服务完整概念。https://martinfowler.com/microservices/
In short, the** microservice architectural style** is an approach to developing a single application as a suite of small services, each running in its own process and communicating with **lightweight **mechanisms, often an **HTTP **resource API. These services are built around business capabilities and independently deployable by fully automated deployment machinery. There is a bare minimum of centralized management of these services, which may be written in different programming languages and use different data storage technologies.– James Lewis and Martin Fowler (2014)
- 微服务是一种架构风格
- 一个应用拆分为一组小型服务
- 每个服务运行在自己的进程内,也就是可独立部署和升级
- 服务之间使用轻量级 HTTP 交互
- 服务围绕业务功能拆分
- 可以由全自动部署机制独立部署
- 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术
3.2、分布式
分布式的困难
- 远程调用
- 服务发现
- 负载均衡
- 服务容错
- 配置管理
- 服务监控
- 链路追踪
日志管理
- 任务调度
- ……
分布式的解决
- SpringBoot + SpringCloud
3.3、云原生
原生应用如何上云。 Cloud Native
上云的困难
- 服务自愈
- 弹性伸缩
- 服务隔离
- 自动化部署
- 灰度发布
- 流量治理
- ……
上云的解决
4、如何学习 SpringBoot
4.1、官网文档架构
查看版本新特性;
https://github.com/spring-projects/spring-boot/wiki#release-notes
前后端分离数据交互
Java 后端和 Vue 前端数据交互一般采用 JSON 格式
基本方式
封装 RespBean 类
package com.xjt.blog.utils;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class RespBean {
private Integer status = 0;
private String msg;
private Object obj;
public static RespBean build(){
return new RespBean();
}
public static RespBean ok(String msg){
return new RespBean(200,msg,null);
}
public static RespBean ok(String msg, Object obj){
return new RespBean(200,msg,obj);
}
public static RespBean error(String msg){
return new RespBean(500,msg,null);
}
public static RespBean error(String msg, Object obj){
return new RespBean(500,msg,obj);
}
}
使用示例:
@RequestMapping("/get")
public Result get(){
HashMap map = new HashMap();
map.put("username","admin");
map.put("password","123456");
Result r = new Result();
r.code(Result.SUCCESS).message("成功访问").data(map);
return r;
}
高级用法
参考 RuoYi 项目
pom.xml
pom.xml 文件标签
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!--继承 SpringBoot 框架的一个父项目,所有自己开发的 Spring Boot 都必须的继承-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--当前项目的 GAV 坐标-->
<groupId>com.bjpowernode.springboot</groupId>
<artifactId>002-springboot-springmvc</artifactId>
<version>1.0.0</version>
<!--maven 项目名称,可以删除-->
<name>002-springboot-springmvc</name>
<!--maven 项目描述,可以删除-->
<description>Demo project for Spring Boot</description>
<!--maven 属性配置,可以在其它地方通过${}方式进行引用-->
<properties>
<java.version>1.8</java.version>
</properties>
<!--maven依赖-->
<dependencies>
</dependencies>
<build>
<plugins>
<!--SpringBoot 提供的打包编译等插件-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<!--保留src/main/java 路径下的xml数据库映射文件-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</project>
常用的 Maven 依赖
<!--springboot的web服务starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--springboot测试starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--热部署-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!--mysql数据库连接驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.25</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
<!--集成thymeleaf模板-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--集成redis数据库-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--集成javax.mail邮件-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.4.1</version>
</dependency>
<!--集成springsecurity安全框架-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId> <!--springsecurity测试(可选)-->
<scope>test</scope>
</dependency>
<!--导入shiro-redis的starter包-->
<dependency>
<groupId>org.crazycake</groupId>
<artifactId>shiro-redis-spring-boot-starter</artifactId>
<version>3.3.1</version>
</dependency>
<!-- hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.4</version>
</dependency>
<!--jwt-->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!--集成druid数据库连接池 springboot2.x以上默认使用com.zaxxer.hikari.HikariDataSource 数据源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.24</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId> <!--druid连接池需要log4j日志框架-->
<version>1.2.17</version>
</dependency>
配置 Annotation Processor
可以帮助我们生成自定义配置的元数据信息,让配置文件和 Java 代码之间的对应参数可以自动定位,方
便开发。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
maven 离线安装 jar
##1、首先到mvnrepository下载jar包
<!-- https://mvnrepository.com/artifact/org.apache.tomcat.embed/tomcat-embed-jasper -->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>9.0.40</version>
</dependency>
##2、安装命令
mvn install:install-file -Dfile=tomcat-embed-jasper.jar -DgroupId=org.apache.tomcat.embed -DartifactId=tomcat-embed-jasper -Dversion=9.0.40 -Dpackaging=jar
核心配置文件
配置文件可以存放在四个不同位置,对应的优先级也不同
application.properties
server.port=8181
server.servlet.context-path=/shiro
spring.application.name=shiro-jsp
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/my-shiro-jsp?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
mybatis.mapper-locations=classpath*:mapper/*.xml
mybatis.type-aliases-package=com.xjt.entity
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
application.yaml
fdfs:
soTimeout: 1500
connectTimeout: 600
thumbImage:
width: 150
height: 150
trackerList:
- 192.168.157.129:22122
spring:
datasource:
driver-class-name: MySQL
url: MySQL
username: root
password: root
type:
com.alibaba.druid.pool.DruidDataSource
profiles:
active: dev #2.4以上版本不同
servlet:
multipart:
max-file-size: 100MB
max-request-size: 1000MB
# 配置 redis
redis:
port: 6379
host: 127.0.0.1
database: 0
timeout: 3000
mvc:
view:
prefix: /
suffix: .html
server:
port: 8080
servlet:
context-path: /
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
cache-enabled: true
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.xjt.shiro.domain
自定义配置
在 SpringBoot 的核心配置文件中,除了使用内置的配置项之外,我们还可以在自定义配置,然后采用注解去读取配置
的属性值。有两种方式的自定义配置项,一是将所有配置项都放在 application.properties,二是拆分出其他配置文件
1、在核心配置文件 applicatin.properties 中,添加两个自定义配置项
在 IDEA 中可以看到这两个属性不能被 SpringBoot 识别,背景是桔色的
@Value("${xjt.name}")
private String name;
2、自定义配置文件,通过注解初始化@PropertySource @Value @ConfigurationProperties
@PropertySource 和 @Value
@Component
@PropertySource(value = {"classpath:props/person.properties"})
public class MyPeople {
@Value("${person.name}")
private String name;
@Value("${person.sex}")
private Integer sex;
@Value("${person.age}")
private Integer age;
@Value("${person.city}")
private String city;
@Value("${person.school}")
private String school;
}
@PropertySource 和 @ConfigurationProperties
@Component
@PropertySource(value = {"classpath:props/datasource.properties"})
@ConfigurationProperties(prefix = "xxxmysql.datasource")
@Data
public class MyJDBC {
private String driver;
private String url;
private String username;
private String password;
}
注意:xxxmysql.datasource 前缀的属性 必须和 MyJDBC 对应是字段名称一致
IDEA 相关
mvn 下载框架的 java 源码
如 springboot 项目无法查看源码用 bash 切换到项目的 目录 有 pom.xml 的地方在终端中输入
mvn dependency:resolve -Dclassifier=sources
项目打包&部署
1、打包并运行 jar
在命令行中运行某个 jar 包
java -jar xxx.jar
java -jar xxx.jar --server.port=8181 #指定端口
Maven
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version> <!--父依赖版本号-->
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.example</groupId>
<artifactId>springboot_thymeleaf_shiro</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
2、打成 war 包
SpringBoot 解决跨域问题跨域
目前大型项目一般采用的是前后端分离,当使用前端 vue + axios 发送跨域请求时会报错,如下
有如下解决方式:
全局配置
config/MyWebMvcConfig.java
@Configuration
public class MyWebMvcConfig extends WebMvcConfigurerAdapter {
/**
* 就是注册的过程,注册Cors协议的内容。
* 如: Cors协议支持哪些请求URL,支持哪些请求类型,请求时处理的超时时长是什么等。
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**") // 所有的当前站点的请求地址,都支持跨域访问。
.allowedMethods("GET", "POST", "PUT", "DELETE") // 当前站点支持的跨域请求类型
.allowCredentials(true) // 是否支持跨域用户凭证
.allowedOrigins("*") // 所有的外部域都可跨域访问。 如果是localhost则很难配置,因为在跨域请求的时候,外部域的解析可能是localhost、127.0.0.1、主机名
.maxAge(60); // 超时时长设置为1小时。 时间单位是秒。
}
}
单个接口使用注解@CrossOrigin
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
@CrossOrigin(origins = "*",maxAge = 3600)
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/getOne/{id}")
public User getOne(@PathVariable("id") Integer id) {
return userMapper.getById(id);
}
}
以 /user/**
开头的请求可以跨域,其他请求 如 /book/**
就不行了
自定义跨域过滤器
1、编写过滤器
public class CrosFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
if (!org.springframework.util.StringUtils.isEmpty(origin)) {
//带cookie的时候,origin必须是全匹配,不能使用*
res.addHeader("Access-Control-Allow-Origin", origin);
}
res.addHeader("Access-Control-Allow-Methods", "*");
String headers = req.getHeader("Access-Control-Request-Headers");
// 支持所有自定义头
if (!org.springframework.util.StringUtils.isEmpty(headers)) {
res.addHeader("Access-Control-Allow-Headers", headers);
}
res.addHeader("Access-Control-Max-Age", "3600");
// enable cookie
res.addHeader("Access-Control-Allow-Credentials", "true");
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
2、注册过滤器
@Bean
public FilterRegistrationBean registerFilter(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.addUrlPatterns("/*");
bean.setFilter(new CrosFilter());
return bean;
}
使用 nginx 反向代理服务器解决跨域问题
1、在 nginx 的 conf 目录下,创建 vhosts 文件夹
2、在 nginx.conf 文件中添加 include vhosts/*.conf
3、vhost 目录下创建 abc.conf 文件
thymeleaf
基础
th:src th:href 路径
WebMvcConfigurer 配置
addResourceHandlers 资源处理器
案例:上传文件保存到项目根路径,想要直接通过 http://127.0.0.1:8888/img/singerPic/123.jpg 访问,需要我们配置 addResourceHandlers 资源处理器
@Configuration
public class FileConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry){
//歌手头像地址
registry.addResourceHandler("/img/singerPic/**").addResourceLocations(
"file:"+System.getProperty("user.dir")+System.getProperty("file.separator")+"img"
+System.getProperty("file.separator")+"singerPic"+System.getProperty("file.separator")
);
}
}
说一下 file:///D:/ 是什么呢??
这是 UNC 定义的一种本地绝对路径的表示方式,可以在浏览器中直接这样访问
来看看这些吧:
String path = "file:" + System.getProperty("user.dir")
+ System.getProperty("file.separator") + "img"
+ System.getProperty("file.separator") + "songListPic"
+ System.getProperty("file.separator");
//项目的绝对路径
System.out.println(System.getProperty("user.dir")); //D:\CodeLearning\JavaLearning\JavaProjects\github_master\王汉远-springboot+vue音乐网站\分章节源码\music142 程序完成\music-server
//系统文件分隔符
System.out.println(System.getProperty("file.separator")); // \ (windows系统是\ Linux系统是 /)
System.out.println(path); //file:D:\CodeLearning\JavaLearning\JavaProjects\github_master\王汉远-springboot+vue音乐网站\分章节源码\music142 程序完成\music-server\img\songListPic\
Lombok
https://www.jianshu.com/p/2543c71a8e45
Lombok 有啥牛皮的?SpringBoot 和 IDEA 官方都要支持它!
最近IDEA 2020 最后一个版本发布了,已经内置了 Lombok 插件,SpringBoot 2.1.x 之后的版本也在 Starter 中内置了 Lombok 依赖。
为什么他们都要支持 Lombok 呢?
以前的 Java 项目中,充斥着太多不友好的代码:
- POJO 的 getter/setter/toString;
- 异常处理;
- I/O 流的关闭操作等等
这些样板代码既没有技术含量,又影响着代码的美观,Lombok 应运而生。
添加 IDEA 工具对 Lombok 的支持
点击 File– Settings 设置界面,安装 Lombok 插件:
引入 jar 包
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
Lombok 常用注解
@Data
作用在类上,生成所有成员变量的 getter/setter 方法和类的 toString 方法,最常用
是以下注解的集合:@ToString @EqualsAndHashCode @Getter @Setter
@Getter、@Setter
作用类上,生成所有成员变量的 getter/setter 方法;
作用于成员变量上,生成该成员变量的 getter/setter 方法。可以设定访问权限及是否懒加载等。
@ToString
作用于类,覆盖默认的 toString()方法,可以通过 of 属性限定显示某些字段,通过 exclude 属性排除某些字段。
@EqualsAndHashCode
作用于类,覆盖默认的 equals 和 hashCode
@NonNull
主要作用于成员变量和参数中,标识不能为空,否则抛出空指针异常。
@NoArgsConstructor, @RequiredArgsConstructor, @AllArgsConstructor
作用于类上,用于生成构造函数。有 staticName、access 等属性。
staticName 属性一旦设定,将采用静态方法的方式生成实例,access 属性可以限定访问权限。
@NoArgsConstructor:生成无参构造器;
@RequiredArgsConstructor:生成包含 final 和@NonNull 注解的成员变量的构造器;
@AllArgsConstructor:生成全参构造器
@Builder
作用于类上,将类转变为建造者模式
@Log
作用于类上,生成日志变量。针对不同的日志实现产品,有不同的注解:
Swagger2
官网:https://swagger.io/
https://zhuanlan.zhihu.com/p/98075551
快速上手
- pom 引入依赖
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
- 项目中新建 SwaggerConfig.java 配置
@Configuration
@EnableSwagger2 //开启swagger2
public class SwaggerConfig implements WebMvcConfigurer {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// 解决静态资源无法访问
registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");
// 解决swagger无法访问
registry.addResourceHandler("/swagger-ui.html")
.addResourceLocations("classpath:/META-INF/resources/");
// 解决swagger的js文件无法访问
registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/");
}
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(xiaomingApiInfo())
.groupName("xiaoxiong")
.select()
//为任何请求处理生成API文档
.apis(RequestHandlerSelectors.any())
//过滤路径
.paths(PathSelectors.any())
.build();
//添加登录认证
/*.securitySchemes(securitySchemes())
.securityContexts(securityContexts());*/
}
private ApiInfo xiaomingApiInfo() {
//作者联系方式
Contact contact = new Contact("xiaoxiong", "https://github.com/BFD2018", "1351655382@qq.com");
return new ApiInfoBuilder()
.title("SwaggerUI演示")
.description("接口文档,描述词省略200字")
.contact(contact)
.version("v1.0")
.build();
}
}
swagger-ui.html 静态资源存放位置:
- com.xjt.controller.SwaggerController.java
可以配置多个 Docket,协同开发 ,谁干了哪些活 很清晰
配置
Docket Bean 配置项
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(xiaomingApiInfo())
.groupName("小明")
.select()
//1、为com.xjt.controller包下Controller生成API文档
//.apis(RequestHandlerSelectors.basePackage("com.xjt.controller"))
//2、为有@Api注解的Controller生成API文档
//.apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
//3、扫描类上有@RestController注解
//.apis(RequestHandlerSelectors.withClassAnnotation(RestController.class))
//为有@ApiOperation注解的方法生成API文档
//.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//扫描方法上有@GetMapping注解
//.apis(RequestHandlerSelectors.withMethodAnnotation(GetMapping.class))
//为任何接口生成API文档
.apis(RequestHandlerSelectors.any())
//过滤路径
.paths(PathSelectors.any())
.build();
//添加登录认证
/*.securitySchemes(securitySchemes())
.securityContexts(securityContexts());*/
}
private ApiInfo xiaomingApiInfo() {
//作者联系方式
Contact contact = new Contact("kuangshenshuo", "http://kuangstudy.com", "1351655382@qq.com");
return new ApiInfoBuilder()
.title("SwaggerUI演示")
.description("接口文档,描述词省略200字")
.contact(contact)
.version("v1.0")
.build();
}
注解配置
@Api(tags = "用户相关模块") //Controller类注解
@Controller
@RequestMapping(value = "/api/")
public class SwaggerController {
@ApiOperation(value = "查找用户") //方法注解
@GetMapping("/user")
@ResponseBody
private String getUser(){
return "hello-world!";
}
@ApiOperation(value = "注册用户")
@PostMapping("/register")
@ResponseBody
private User registerUser(String name,Integer age){
User user = new User();
user.setName(name);
user.setAge(age);
return user;
}
}
swagger-ui 上显示:
@ApiModel(value = "User-model")
@Data
public class User {
@ApiModelProperty("User-name")
private String name;
@ApiModelProperty("User-age")
private Integer age;
private String phone;
}
swagger-ui 上显示:(注意:只有 Controller 方法中返回 Model 才能显示)
@ApiOperation(value = "注册用户")
@PostMapping("/register")
@ResponseBody
private User registerUser(@ApiParam(value = "用户名") String name, @ApiParam(value = "用户年龄") Integer age){
User user = new User();
user.setName(name);
user.setAge(age);
return user;
}
swagger-ui 上显示:
生产环境去掉 Swagger
com.xjt.config.SwaggerConfig.java
@Bean
public Docket docket2(Environment environment) {
//设置要显示的swagger环境
Profiles profiles = Profiles.of("dev", "test");
//通过environment.acceptsProfiles() 判断是否处于dev 或test环境
boolean flag = environment.acceptsProfiles(profiles);
return new Docket(DocumentationType.SWAGGER_2)
.groupName("小刚")
.apiInfo(xiaogangApiInfo())
.enable(flag) //开启swagger2
.select()
.apis(RequestHandlerSelectors.basePackage("com.xjt.controller"))
.build();
}
springboot 配置文件
显示出来了
日志配置
背景:我们都知道 springboot 默认日志是打印在控制台中的,不会以文件的形式进行保存。那么日后系统上线肯定是有需要对日志进行定位分析问题的,那么如何实现将控制台输出的日志保存起来?
话不多说,实际效果如下,如果是你预期的那样,咱们接着往下看。
如下是集成,按步骤来:
1、在项目的 resources 目录下创建一个名为 logback-spring.xml 的日志配置文件,配置文件名最好跟我一样;
2、编写 xml 文件内容:
code 中每句都给出了注释,方便你们理解。
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<!-- 引入默认得配置文件 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<!-- 模块名标识日志名称 -->
<springProperty scope="context" name="springAppName" source="spring.application.name"/>
<!-- info日志单文件大小限制 -->
<springProperty scope="context" name="logback.fileInfoLog.maxFileSize" source="logback.fileInfoLog.maxFileSize" defaultValue="200MB" />
<!-- info日志最大保留时长单位天 -->
<springProperty scope="context" name="logback.fileInfoLog.maxHistory" source="logback.fileInfoLog.maxHistory" defaultValue="15" />
<!-- info日志文件总大小,超过该大小,旧得即将删除 -->
<springProperty scope="context" name="logback.fileInfoLog.totalSizeCap" source="logback.fileInfoLog.totalSizeCap" defaultValue="100GB" />
<!-- error日志单文件大小限制 -->
<springProperty scope="context" name="logback.fileErrorLog.maxFileSize" source="logback.fileErrorLog.maxFileSize" defaultValue="200MB" />
<!-- error日志最大保留时长单位天 -->
<springProperty scope="context" name="logback.fileErrorLog.maxHistory" source="logback.fileErrorLog.maxHistory" defaultValue="15" />
<!-- error日志文件总大小,超过该大小,旧得即将删除 -->
<springProperty scope="context" name="logback.fileErrorLog.totalSizeCap" source="logback.fileErrorLog.totalSizeCap" defaultValue="100GB" />
<!-- http日志单文件大小限制 -->
<springProperty scope="context" name="logback.fileHttpLog.maxFileSize" source="logback.fileHttpLog.maxFileSize" defaultValue="200MB" />
<!-- http日志最大保留时长单位天 -->
<springProperty scope="context" name="logback.fileHttpLog.maxHistory" source="logback.fileHttpLog.maxHistory" defaultValue="15" />
<!-- http日志文件总大小,超过该大小,旧得即将删除 -->
<springProperty scope="context" name="logback.fileHttpLog.totalSizeCap" source="logback.fileHttpLog.totalSizeCap" defaultValue="100GB" />
<!-- 日志目录 -->
<springProperty scope="context" name="logback.rootDir" source="logback.rootDir" defaultValue="logs"/>
<!-- 控制台输出得日志格式 -->
<property name="CONSOLE_LOG_PATTERN"
value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>
<!-- 日志文件输出得日志格式 -->
<property name="FILE_LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %t [%c:%L]-%m%n"/>
<!-- 控制台输出 -->
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${CONSOLE_LOG_PATTERN}</pattern>
</layout>
</appender>
<!-- info日志得设定 -->
<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${logback.rootDir}/${springAppName}.log</file>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" >
<!--路径-->
<fileNamePattern>${logback.rootDir}/%d{yyyy-MM,aux}/%d{yyyy-MM-dd,aux}/${springAppName}-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxFileSize>${logback.fileInfoLog.maxFileSize}</maxFileSize>
<maxHistory>${logback.fileInfoLog.maxHistory}</maxHistory>
<totalSizeCap>${logback.fileInfoLog.totalSizeCap}</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<!-- 错误日志 -->
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${logback.rootDir}/${springAppName}-error.log</file>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy" >
<!--路径-->
<fileNamePattern>${logback.rootDir}/%d{yyyy-MM,aux}/%d{yyyy-MM-dd,aux}/${springAppName}-error-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxFileSize>${logback.fileErrorLog.maxFileSize}</maxFileSize>
<maxHistory>${logback.fileErrorLog.maxHistory}</maxHistory>
<totalSizeCap>${logback.fileErrorLog.totalSizeCap}</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<!-- http日志 -->
<appender name="httpInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %m%n</pattern>
</encoder>
<file>${logback.rootDir}/${springAppName}-http.log</file>
<!--滚动策略-->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!--路径-->
<fileNamePattern>${logback.rootDir}/%d{yyyy-MM,aux}/%d{yyyy-MM-dd,aux}/${springAppName}-http-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxFileSize>${logback.fileHttpLog.maxFileSize}</maxFileSize>
<maxHistory>${logback.fileHttpLog.maxHistory}</maxHistory>
<totalSizeCap>${logback.fileHttpLog.totalSizeCap}</totalSizeCap>
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<appender name="ASYNC_consoleLog" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="consoleLog"/>
</appender>
<appender name="ASYNC_fileInfoLog" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="fileInfoLog"/>
</appender>
<appender name="ASYNC_fileErrorLog" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="fileErrorLog"/>
</appender>
<appender name="ASYNC_httpInfoLog" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="httpInfoLog"/>
</appender>
<root level="info">
<appender-ref ref="ASYNC_consoleLog" />
<appender-ref ref="ASYNC_fileInfoLog" />
<appender-ref ref="ASYNC_fileErrorLog" />
</root>
<logger name="log_http" additivity="false" level="INFO">
<appender-ref ref="ASYNC_httpInfoLog"/>
</logger>
</configuration>
3、配置日志配置中所提到的 springAppName;
4、使用这个默认不用配置 pom 依赖,最新的 spring-boot-starter-web 中已经集成了。如下,重启下项目就能自动生成日志文件了,而且是实时写入的,控制台输出什么,立马就更新进到该 xxx.log 里头。
记得,配置日志完后,记得刷新下 maven 或者关闭下项目重新打开,以免误导大家以为日志配置没用。
原文链接:https://blog.csdn.net/weixin_43970743/article/details/115767763
另外:
想要在控制台打印 sql,如下:
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台打印sql执行语句
cache-enabled: true
mapper-locations: classpath:/mapper/*.xml #映射XXXmapper.xml文件路径
type-aliases-package: com.xjt.travel.domain #包名