SpringBoot
简化配置,基于约定优于配置的思想
Spring缺点:1.配置繁琐2.依赖繁琐
Spring功能:
1.自动配置:运行时自动配置
2.起步依赖:传递依赖
3.辅助功能:嵌入服务器,安全,健康检查,外部配置等
是Spring的优化
Maven依赖 父工程
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
作用:1.标识该项目是一个Springboot项目 2.管理各项技术的版本号
引导类
@SpringBootApplication
public class Learn2Application {
public static void main(String[] args) {
SpringApplication.run(Learn2Application.class, args);
}
}
使用jar的打包方式,通过引导类使用
@SpringBootApplication注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
@SpringBootConfiguration:标记当前为Springboot配置类
@EnableAutoConfiguration:开启自动配置功能
@ComponentScan:包扫描器
起步依赖
核心
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
在父工程指定了版本信息,版本锁定
测试
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
@SpringBootTest
public class webappTest {
@Autowired
private helloController Controller;
@Test
public void test() {
}
}
必须要@S注解springBootTest:作用加载启动类并生成springboot应用程序的上下文,测试的组件,服务,功能
测试类必须和启动类同一个包或者子包中!! 否则需要设置属性指定启动类
@SpringBootTest(classes =webApplication.class )
热部署:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
Bean:
注入容器:2种方法
1.扫包
2.配置文件创建引入
属性绑定:
company:
name: ry
address: cq
post: 6
1.使用@Value注解
@Data
@ToString
@Component
public class Company {
@Value("${company.name}")
private String name;
@Value("${company.address}")
private String address;
@Value("${company.post}")
private String post;
}
2.使用@ConfigurationProperties
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "company")
public class Company {
// @Value("${company.name}")
private String name;
// @Value("${company.address}")
private String address;
// @Value("${company.post}")
private String post;
}
可以将和配置文件中的指定前缀属性进行绑定
配置文件:
使用yml,properties,yaml进行配置,
优先级:properties>yml>yaml
键值对
server.port=8080
##自定义内容如下
name=abc
yml ,在冒号之后需要有空格
server:
port: 8080
优先级properties>yml>yaml
YAML
以数据为中心比xml简洁 数据前必须有空格
能显示程度,缩进不允许使用Table只允许空格
同级左对齐 #表示注释
数据格式:
1.对象(map)键值对集合
#行内写法 也是需要空格间隔
server: {port: 8081}
#
server:
port: 8081
2.数组 斜杠开始 依旧需要空格隔开
address:
- shanghai
- chongqing
#行内写法
address: [shanghai,chongqing]
3.纯量
单引忽略转义字符
双引号识别转义字符
msg1: 'hello \n word'
msg2: "hello \n word"
参数引用
name: abc
person:
name:${name}
读取数据的方式:
1.@Values
@RestController
public class Hello {
@Value("${address1[0]}")
private String name;
@RequestMapping("/hello")
public String hello() {
return "Hello World!"+this.name;
}
}
2.Environment
3.@ConfigurationProperties
如果不指定会优先找名为name 和age的属性 不会导入person下的属性
server:
port: 8080
name: ry
person:
name: ${name}
age: 18
person2: {name: zhangsan2, age: 18}
address1: [shanghai,chongqing]
address2:
- shanghai
- chongqing
- xian
加入对应的标记:
@Data
@Component
@ConfigurationProperties(prefix = "person")
public class person {
private String name;
private int age;
}
需要加入这个依赖实现提示功能
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
proflie实现不同环境的配置:
@Profile注解 可以标识配置类所属环境
通过@Value 来注入值
多文件
创建多个文件,添加不同的后缀
dev开发,pro生产,test测试
想要使用哪个文件:active代表后缀
spring:
profiles:
active: pro
一个文件多个文档
使用—分割文档设置其spring:
profiles: pro 的标识
再spring:
profiles:
active: pro激活
server:
port: 8081
name: ry
person:
name: ${name}
age: 18
person2: {name: zhangsan2, age: 18}
address1: [shanghai,chongqing]
address2:
- shanghai
- chongqing
- xian
msg1: 'hello \n word'
msg2: "hello \n word"
Spring:
profiles: dev
devtools:
restart:
enabled: true #开启热部署
additional-paths: src/main/java #指定监控的目录
exclude: test/**
---
server:
port: 8082
spring:
profiles: test
---
server:
port: 8083
spring:
profiles: pro
---
spring:
profiles:
active: dev
虚拟机设置选择
在VM options指定-Dspring.profiles.active=dev
命令行参数:
java-jar xxx.jar --spring.profile.active=dev
内部配置加载顺序
高优先级会覆盖低优先级,都会生效可以互补
从大到小
1.file:/config/: 当前项目下的/config目录下
2.file:/ :当前项目的根目录
3.classpath:/config/:classpath的/config目录
4.classpath:/ :classpath的根目录
注意1和2不会打入jar包,命令打开jar包会读取3,4的配置
外部配置加载顺序
1.方式一在命令中指定参数
方式二:命令行中指定配置文件 java-jar xxx.jar --spring.config.location=配置文件目录
2.将配置文件放在jar同一级目录
3.将配置文件放jar同一级别的目录下的config文件。优先级最高
Spring高级:
SpringBoot自动配置:
Condition,通过这个功能可以实现选择性的创建Bean操作,导入坐标以后自动配置一些bean
@Conditional注解进行选择是否创建bean
继承接口进行设置
@Configuration
public class UserConfig {
@Bean
@Conditional(ClassCondition.class)
public User user(){
return new User();
}
}
public class ClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//条件
return true;
}
}
切换内置服务器
tomcat,Netty,Jetty,Undertow
排除默认tomcat坐标加入其他服务器坐标,原理:Condition
<!--排除tomcat-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--添加其他服务器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
启动成功
@Enable*注解
动态启动某些功能,底层原理使用@Import注解导入一些配置类,实现Bean的动态加载
@ComponenScan扫描范围:当前引导类所在包和及其子包
@Import注解:都会被Spring创建并放入IOC容器
对Import注解进行封装 ,写注解在注解中导入Import配置类
package com.example.learn2;
import com.example.learn2.config.UserConfig;
import org.springframework.context.annotation.Import;
import java.lang.annotation.*;
@Import(UserConfig.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EnableUser {
}
@EnableUser
使用注解就可以导入Bean
@Import注解
4种导入方式
1.导入Bean,spring自动创建但不一定是类名
@SpringBootApplication
//@EnableUser
@Import(User.class)
public class Learn2Application {
public static void main(String[] args) {
ConfigurableApplicationContext context = SpringApplication.run(Learn2Application.class, args);
Map<String, User> system = context.getBeansOfType(User.class);
System.out.println(system.toString());
}
}
2.导入配置类,导入所以配置类的Bean
可以不加@Configuration注解
3.导入ImportSelector实现类,一般用于加载配置文件中的类
public class myImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[]{"com.example.learn2.pojo.User"};//可以导入多个类,但必须全称
}
}
@Import(myImportSelector.class)//使用注解导入
4.导入ImportBeanDefinitionRegeistrar实现类
public class myImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//类似于创建bean
BeanDefinition user= BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
//注册bean并写入名字
registry.registerBeanDefinition("user",user);
}
}
//使用@Import导入
@Import(myImportBeanDefinitionRegistrar.class)
@EnableAutoConfiguration
实际是@Import导入AutoConfigurationImportSelector.class}
META-INF/Spring.factories下定义了大量配置类,当Springboot启动时,会加载这些配置类,初始化Bean
Condition满足条件加载Bean
Starter案例,导入坐标。加载Bean
步骤:
创建redis-spring-boot-autoconfigure模块
创建redis-spring-boot-starter 模块 依赖redis-spring-boot-autoconfigure的模块
在redis-spring-boot-autoconfigure模块中初始化Jedis的Bean,并定义META-INF/spring.factories文件
在测试模块中引入自定义redis-starter依赖,测试获取的Jedis的Bean,操作redis
SpirngBoot监听机制
是对java监听机制的一种封装,
java中:1.事件,Event 继承java.until.EventObject
2.事件源:Source,任意对象
3.监听器:Listener,实现java.until.EventListener接口对象
Springboot中:
ApplicationContextlnitalizer,
在IOC容器加载之前实现
META-INF/spring.factories下配置,全路径名=自己实现接口的全路径名
org.springframewor…ApplicationContextlnitalizer=edcu.ry…myApplicationContextlnitalizer
SpringApplicationRunListener
META-INF/spring.factories下配置
类似生命周期对应的方法监听执行
CommandLineRunner
参数:配置参数
放入IOC容器运行时执行
ApplicationRuner
参数:配置参数
放入IOC容器运行时执行
作用:可以在用户没访问时候执行方法,来将数据库加入缓存来预热
Springboot启动流程分析
banner.txt文件resources下替换加载时候的Springboot图
Springboot监控
自带监控功能Actuator,可以实现对程序内部运行监控,比如监控状况,Bean加载,配置属性,日志信息等
<!-- 监控使用-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
访问 http:/localhost:8080/actuator
监控详情的程度
http://localhost/actuator/health查看监控情况
开启所有健康详情
management.endpoint.health.show-details=always
#暴露所有的url,端口
management.endpoints.web.exposure.include=*
SpringAdmin 开源监控
监控着:服务器模块
依赖:
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-server</artifactId>
</dependency>
配置
访问端口
server.port=9000
被监控的:客户端模块
依赖
<dependency>
<groupId>de.codecentric</groupId>
<artifactId>spring-boot-admin-starter-client</artifactId>
<version>3.1.5</version>
</dependency>
配置
#admin 服务器端口 监控详情
spring.boot.admin.client.url=http://localhost:9000
management.endpoint.health.show-details=always
#暴露的url端口 客户端的基本地址
management.endpoints.web.exposure.include=*
spring.boot.admin.client.instance.service-base-url=http://localhost:80
Spring Data的数据访问:
默认整合SpringData
也可以使用 JDBC模块 JPA模块 redis等等…
1.添加依赖: mysql为例子
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
2.配置文件写入
spring:
datasource:
url: jdbc:mysql://localhost:3306/springbootdata?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 303030
driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
configuration:
#开启驼峰命名
map-underscore-to-camel-case: true
3.创建实体类和dao层接口
@Mapper
public interface CommentMapper {
/**
* a
* @param id
* @return Comment
*/
Comment selectComment(int id);
int deleteComment(int id);
int insertComment(Comment comment);
int updateComment(Comment comment);
}
加上@Mapper的注解 标识 Spirngboot容器才可以加入mapper-locations
或者在启动类上加上@MapperScan(“com.example.springbootconbindata.dao”)批量扫包
4.如果使用xml实现接口 需要修改配置文件 mapper-locations指定位置
mybatis:
# mapper.xml文件位置
mapper-locations: classpath:mapper/*.xml
configuration:
#打印sql
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#开启驼峰命名
map-underscore-to-camel-case: true
Mybatis-Plus:
mybatis增强工作 不改变Mybatis
1.依赖
2.创建实体类:
@Data
@ToString
//绑定表明
@TableName("t_comment")
public class Comment {
@TableId(type= IdType.AUTO)
private int id;
private String content;
private String author;
private Integer aId;
}
@TableName(“”) 实体类与表关联
@TableId 标识主键 以及指定生成主键策略
@TbaleFieId 将实体属性与表的列绑定
3.创建接口
@Mapper
public interface commentMapper extends BaseMapper<Comment> {
}
只用继承 BaseMapper注解 里面包含所有的单表操作接口 直接调用
4.扩展 MybatisPuls 的service
接口继承
public interface CommentService extends IService<Comment> {}
实现类继承
@Service
public class CommentServiceImpl extends ServiceImpl<CommentMapper,Comment> implements CommentService {
}
Springboot 集成 Thymeleaf
依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
配置文件:
thymeleaf:
#页面缓存
cache: false
encoding: UTF-8
mode: HTML5
prefix: classpath:/templates/
suffix: .html
html例子
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1 >nihao thymeleaf</h1>
<!--${.....}中的是模板引擎的变量-->
<h1 th:text="${name}"></h1>
</body>
</html>
常见th:标签
th:each 使用
和jsp中c:foreach 差不多 冒号前面是遍历的每一个对象
<fieldset>
<legend>获取id为1的评论详情</legend>
<table border="1">
<tr><td>评论内容</td><td>评论作者</td></tr>
<tr th:each="comment : ${commentList}">
<td th:text="${comment.getContent()}"></td>
<td th:text="${comment.author}"></td>
</tr>
</table>
</fieldset>
th:object:
*{}中可以直接写对象的属性
<table border="1">
<tr><td>评论内容</td><td>评论作者</td></tr>
<tr th:object=" ${comment}">
<td th:text="*{content}"></td>
<td th:text="*{author}"></td>
</tr>
</table>
Sringboot静态资源
Springboot默认设置了静态访问资源 将/**所有访问映射到一下目录
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
也可以在配置文件中设置 来修改默认静态资源目录
web:
resources:
static-locations: classpath:/static/
th:herf 和th:src 使用
<link th:href="@{/css/bootstrap.min.css}" href="login/css/bootstrap.min.css" rel="stylesheet">
<link th:href="@{/css/signin.css}" href="login/css/signin.css" rel="stylesheet">
</head>
<body class="text-center">
<!-- 用户登录form表单 -->
<form class="form-signin">
<img class="mb-4" th:src="@{/img/login.jpg}" src="login/img/login.jpg" width="72" height="72">
SpringMvc的扩展:
1.视图管理器
快速添加控制器跳转
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry
.addViewController("/o/c")
.setViewName("login");
}
2.静态资源配置
配置文件会覆盖默认配置
web:
##本地资源路径
resources:
static-locations: classpath:/static/
mvc:
##映射
static-path-pattern: /source/**
重写的方式 会添加不会覆盖
!!!但加上@EnableMvc 会覆盖默认配置
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/resource/**")
.addResourceLocations("classpath:/resource/");
}
3.注册拦截器
创建拦截器
/**
* @author 冉毓
*/
public class LoginInterceptor implements HandlerInterceptor {
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
注册拦截器(注意放行静态资源)
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/source/**","/ok");
}
4.CORS跨域
协议,端口号,主机 相同的称为同源
CORS是W3C跨域资源共享技术,目前是解决前端跨域请求问题,客服了ajax只能同源使用
3种方式实现:@CrossOrigin注解 ,全局配置实现 , 基于过滤器实现
注解:
@RequestMapping(value = "/getData")
@ResponseBody
@CrossOrigin(value = "http://localhost:8081",maxAge = 3600,allowedHeaders = "*")
public List<User> addUser() {
LambdaQueryWrapper<User> queryWrapper=new LambdaQueryWrapper<>();
List<User> list = userService.list(queryWrapper);
return list;
}
全局配置:
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
// .allowedOrigins("*")
.allowedOriginPatterns("*")
.allowedMethods("GET","POST","PUT","DELETE","OPTIONS","HEAD")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
全局异常处理:
全局处理机制:
Spring mvc 框架中通过HandlerExceptionResolver机制来实现全局异常处理功能
实现方式:
1.实现HandlerExceptionResolvr接口
public class ExceptionH implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return new ModelAndView("login");
}
}
2.使用@ControllerAdvice 注解和@ExceptionHandler注解
@ExceptionHandler来定义异常处理方法
3.前后端分类 使用@RestControllerAdvice
@RestControllerAdvice 是@ExceptionHandler和@ResponseBody组合
4.Springboot全局异常处理扩展
如果没有部署HandlerException 转发给/error
st;
}
全局配置:
```java
@Override
public void addCorsMappings(CorsRegistry registry) {
registry
.addMapping("/**")
// .allowedOrigins("*")
.allowedOriginPatterns("*")
.allowedMethods("GET","POST","PUT","DELETE","OPTIONS","HEAD")
.allowCredentials(true)
.maxAge(3600)
.allowedHeaders("*");
}
全局异常处理:
全局处理机制:
Spring mvc 框架中通过HandlerExceptionResolver机制来实现全局异常处理功能
实现方式:
1.实现HandlerExceptionResolvr接口
public class ExceptionH implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
return new ModelAndView("login");
}
}
2.使用@ControllerAdvice 注解和@ExceptionHandler注解
@ExceptionHandler来定义异常处理方法
3.前后端分类 使用@RestControllerAdvice
@RestControllerAdvice 是@ExceptionHandler和@ResponseBody组合
4.Springboot全局异常处理扩展
如果没有部署HandlerException 转发给/error
[外链图片转存中…(img-fQ18sf8F-1718805199644)]