视频:基础篇-01_springboot概述_哔哩哔哩_bilibili
介绍
spring boot 是spring提供的一个子项目,用于快速构建spring应用程序
spring构建: 1 导入依赖繁琐 ; 2 项目配置繁琐
spring Framework: 核心
spring Boot :快速构建spring项目
spring Data: 数据获取
spring cloud:服务治理
spring AMQP:消息传递
spring Security: 认证授权
springboot特点
- 起步依赖: 本质是一个maven坐标,整合了完成一个功能需要的所有坐标
- spring-boot-starter-web包,包含了多个开发web相关的依赖,整合在一起
- 自动配置: 遵循约定大于配置,在boot程序启动后,一些bean对象会自动注入道ioc容器
- 其他特性
- 内嵌的tomcat,jetty(无需部署war文件,只需要打jar包)
- 外部化配置(修改项目外面的配置文件)
- 不需要xml配置(properties/yml)
搭建一个最简单的项目
如果是1.8版本: server url 改成:start.aliyun.com ,java选择8
// 1 启动类注解 @SpringBootApplication
@SpringBootApplication
public class Demo2Application {
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
}
// 2 controller类注解 @RestController
@RestController
public class UserController {
@GetMapping("/hello")
@ResponseBody
public String hello(){
System.out.println("Hello");
return "Hello";
}
}
再加个配置文件
<?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>
<!-- 3 boot 工程的父工程,用于管理起步依赖的管理 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.2</version>
</parent>
<groupId>org.example</groupId>
<artifactId>testPeizhi</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!-- 4 web的依赖包 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
配置文件:application.properties / application.yml
application.properties相关配置的官方文档:Common Application Properties
bootstrap不生效
yml
server:
port: 7080
context-path: /test
# 字段获取
@Value("${server.port}")
# 如果没配置,会报错,可以设置默认值
@Value("${键名:}")
# 类上获取
@ConfigurationProperties(prefix = "email")
@Component
hobbies:
- 打篮球
- 打豆豆
# 获取数组,适用@ConfigurationProperties,不适用@Value
private List<String> hobbies;
解决方法:解决@value获取不到yaml数组的问题_@value 数组-CSDN博客
Java基础篇--YML简介_java yml-CSDN博客
手动创建module
Bean管理
bean扫描
@SpringBootApplication
组合:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
@Componentscan 一般不配置路径,默认扫描启动类所在的包,及其子包
如果在其他地方的包也要扫描到:
@SpringBootApplication
@ComponentScan(basePackage = "com.chinaoly")
bean注册
@Component 声明bean的基础注解 不属于以下三类的,用此注解
@Controller component的衍射注解 标注在控制器上
@Service component的衍射注解 标注在业务类上
@Repository component的衍射注解 标注在数据访问类上(用于和mybatis整合,用的少)
如果是第三方的文件注入
@Bean
@Import
不推荐放在启动类,建议单独的配置文件
@Configuration
public class Commonfig{
@Bean // @Bean("resolver1") 改名
public Resolver resolver(){
return new Resolver();
}
@Bean // 用参数方式从yml获取配置值
public Resolver resolver2(@Value("${email.name}")String name){
return new Resolver();
}
}
@Import(Commonfig.class) //如果Commonfig不在启动类的包和子包下,使用import注解可以导入Commonfig以及里面的bean
@Import({xxx.class,xxx.class...})
或
@Import(CommonImportSelector.class)
public class CommonImportSelector implemenets ImportSelector{
@Override
public String[] selectImport(AnnotationMetadata importingClassMetadata){
return new String[]{"...XXX.class","...xxx.class"}
}
}
检查注入情况
ConfigurableApplicationContext context = SpringApplication.run(Main.class, args);
XXX xxx = context.getBean(XXX.class); // context.getBean("name") beanName默认是方法名
System.out.println(xxx);
获取resource下的文件
@Configuration
public class ClassImporter implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
InputStream is = ClassImporter.class.getClassLoader().getResourceAsStream("11111.text");
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = null;
try {
while ((line = br.readLine()) != null){
System.out.println(line);
}
br.close();
}catch (IOException e){
e.printStackTrace();
}finally {
if (br != null){
try {
br.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
return new String[]{"com.example.extend.Country"};
}
}
注册条件
SpringBoot提供了设置注册生效条件的注解:
@Conditional
此注解用起来麻烦,常用衍射注解
@ConditionalOnProperty 配置文件中存在对应的数下,才声明bean
@ConditionalOnMissingBean 当不存在当前类型的bean时,才声明当前bean
@ConditionalOnClass 当前环境存在指定的类时,才声明bean
@Configuration
public class CommonConfig {
// country 下有name,ip 都配置了才生效
@ConditionalOnProperty(prefix = "country",name = {"name","ip"})
@Bean
public Country restTemplate(@Value("${country.name}")String name, @Value("${country.ip}")String ip){
Country country = new Country();
country.setUsername(name);
country.setIp(ip);
return country;
}
// 不存在country,则注入
@Bean
@ConditionalOnMissingBean(User.class)
public Country country(){
}
// 某个类存在才注入
@Bean
@ConditionalOnClass(name = "全类名")
public Country country1(){
}
}
自动配置
遵循约定大于配置的原则,在boot程序启动后,起步依赖中的一些bean对象会自动注入到ioc容器中。
内容参考视频,存在如下问题
spring 6.0.1或spring boot 3的自动装配问题 spring.factoriess不生效问题_spring.factories 不生效-CSDN博客
校验
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
参数上加校验
实体类上加校验
JWT
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.4.0</version>
</dependency>
// 获得token
private String getToken(){
Map<String, Object> chaims = new HashMap<>();
chaims.put("id","");
chaims.put("name","");
String token = JWT.create()
.withClaim("user", chaims)
.withExpiresAt(new Date(System.currentTimeMillis() + 1000 * 60 * 60 * 3))
.sign(Algorithm.HMAC256("momolihahahah"));
return token;
}
// 验证token
private boolean parseToken(String token){
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("momolihahahah")).build(); // JWT验证对象
DecodedJWT decodedJWT = jwtVerifier.verify(token);
Map<String, Claim> claims = decodedJWT.getClaims();
Claim user = claims.get("user");
Map<String, Object> chaims = user.asMap();
return true;
}
登录认证-拦截器
注解
@RequestHeader
@PostMapping("/fangwen")
public Boolean fangwen(@RequestHeader(name = "Authorization")String token){
return false;
}
@JsonIgnore
// 例如密码,转换成json返回的时候不希望显示出来,可用此注解
@JsonIgnore
private String password;
mybatis:启动 数据库_ 映射 实体类的驼峰命名
mybatis:
configuration:
map-underscore-to-camel-case: true
ThreadLocal工具类: P22
// ThreadLocal 线程安全,但用完要清除,避免内存泄露
public class ThreadLocalUtil {
private static final ThreadLocal THREAD_LOCAL = new ThreadLocal();
public static <T> T get(){
return (T) THREAD_LOCAL.get();
}
public static void set(Object obj){
THREAD_LOCAL.set(obj);
}
public static void remove(){
THREAD_LOCAL.remove();
}
}
@RequestBody
// 请求的参数以json格式传输,转换成 实体类 或 map,用RequestBody注解
@RequestMapping("/hello")
public String hello(@RequestBody MyEmail email) {
return "Hello " ;
}
@RequestParam
@RequestMapping("/hello")
@ResponseBody
public String hello(@RequestParam(name = "name", defaultValue = "unknown user") String name) {
List<String> hobbies = myEamil.getHobbies();
System.out.println();
// hobbies.forEach(e-> System.out.println(e));
return "Hello " + name;
}
@RequestParam和@PathVirable和@RequestBody区别-CSDN博客
@JsonFormat
// json实体中日期返回格式配置
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
分组校验
default分组
自定义注解: P33
集成redis
多环境开发: P44
如果特定环境中的信息和通用环境中的信息冲突,特定环境的生效
如果配置信息多,拆分
共性配置还是非常多,继续拆分维护 P45