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>
引导类
@SpringBootApplication
public class Learn2Application {
public static void main(String[] args) {
SpringApplication.run(Learn2Application.class, args);
}
}
使用jar的打包方式,通过引导类使用
起步依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
在父工程指定了版本信息,版本锁定
配置文件:
使用yml,properties,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实现不同环境的配置:
多文件
创建多个文件,添加不同的后缀
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
factId>
配置
访问端口
```properties
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