SpringBoot
概述
SpringBoot快速入门
SpringBoot起步依赖原理分析
spring-boot-starter-parent
spring-boot-starter-web
这几个起步依赖都是springboot定义好了的各种技术jar包最优搭配,不会造成依赖冲突
Springboot配置
配置文件分类
properties
server.port=8080
yml
server:
port: 8080
yaml
server:
port: 8080
小结:
- springboot加载顺序不同,提供了两种配置文件类型:properties和yml/yaml
- 默认配置文件名称是: application
- 在同一级目录下配置文件类型的加载顺序优先级是properties>yml>yaml
YAML
yaml不是一种标记语言,他是以数据为核心的,省去其他的繁琐的语法格式
基本语法
- 大小写敏感
- 数据值前边必须有空格,作为分隔符
- 使用缩进表示层级关系
- 缩进时不允许使用Tab键,只允许使用空格(各个系统Tab对应的空格数目可能不同,导致层次混乱)。
- 缩进的空格数目不重要,只要相同层级的元素左则对齐即可
- #表示注释,从这个字符一直到行尾,都会被解析器忽略。
数据格式
-
对象(map):键值对的集合
person: name: zhangsan #行内写法 person: {name: zhangsan}
-
数组:一组按次序排列的值
address: - beijing - shanghai #行内写法 address: [beijing,shanghai]
-
纯量:单个的,不可再分的值
msg1: 'hello \n word' #单引号忽略转义字符直接输出 msg2: "hello \n word" #双引号会识别换行
参数引用
-
name: lisi person: name: ${name}
获取数据
-
//第一种通过@Value注解注入JavaBean属性获取数据 @Value("键名称") private String name; //第二种通过创建Environment对象,通过调用方法获取 Environment对象获取数据 private Environment env; env.getProperty("键名称"); //第三种通过给JavaBean添加@ConfigurationProperties注解来将yaml数据注入JavaBean属性中 @ConfigurationProperties(prefix = "数据键名称") public class Person{ private String name; private int age; private String address; getter/setter/toString.. } sout(Person)
profile
我们在开发Spring Boot应用时,通常同一套程序会被安装到不同环境,比如:开发、测试、生产等。其中数据库地址、服务器端口等等配置都不同,如果每次打包时,都要修改配置文件,那么非常麻烦。profile功能就是来进行动态配置切换的
-
profile配置方式
-
多profile文件方式
-
通过创建多个Properties 使用 spring.profile.active=配置名称
spring.profile.active=dev/test/pro
-
-
yml多文档方式
-
通过在yml文档使用
---
分隔多环境配置,使用spring.profile标识 -
再使用
spring.profile.active=配置名称
激活配置--- server: prot: 8080 spring: profile: dev --- server: prot: 8081 spring: profile: test --- server: prot: 8082 spring: profile: pro ---
-
-
-
profile激活方式
- 配置文件:在配置文件中配置:spring.profiles.active=dev
- 虚拟机参数:在VM options 指定:-Dspring.profile.active=dev
- 命令行参数:java -jar xxx.jar --spring.profile.active=dev
内部加载顺序
springboot程序启动时,会从一下位置加载配置文件:
- file:…/config/:当前项目下的/config目录下
- file:./ :当前项目根目录
- classpath:/config/: classpath的/config目录
- classpath:/ classpath的根目录
加载那些为上文的排列顺序,高优先级配置的属性会生效
外部加载顺序
- 命令行加载
- 外部文件加载
- 外部配置文件在同级目录下会覆盖加载相同的配置
- 外部配置config文件夹在同级目录内也会覆盖加载相同的配置
Springboot整合其它框架
Springboot高级
Springboot原理分析
自动配置
condition
spring4.0之后添加的条件功能,具体根据条件自动获取对象初始化实现方法
-
创建配置类添加配置类注解
@Configuration
-
创建方法 返回对象,添加
@Bean
注解 -
添加
@Conditionl
注解传入参数条件加载类 -
创建条件类实现Condition接口复写matches方法
//配置类 @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 false; } }
condition小结
-
自定义条件:
-
定义条件类:自定义类实现Condition接口,重写matches方法,在matches方法中进行逻辑判断,返回boolean值。matches方法两个参数:
-
context: 上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等。
-
metadata:元数据对象,用于获取注解属性。
-
-
判断条件:在初始化Bean时,使用==@conditional(条件类.class)==注解
-
-
SpringBoot提供的常用条件注解:
- conditionalonProperty: 判断配置文件中是否有对应属性和值才初始化Bean
- conditionalonclass: 判晰环境中是否有对应字节码文件才初始化Bean
- conditionalonMissingBean: 判断环境中没有对应Bean才初始化Bean
定义条件类:自定义类实现Condition接口,重写matches方法,在m atches方法中进行逻辑判断,返回
切换内置web服务器
Enable注解
-
SpringBoot不能直接获取在其他工程中定义的Bean
-
原因是在组件扫描范围,当前引导类所在包及其子包
-
三种解决方案
-
使用@ComponentScan扫描com.itheima.config包
-
可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器
-
可以对Import注解进行封装。
重点:Enable注解底层原理是使用@Import注解实现Bean的动态加载
-
自定义starter实现
SpringBoot提供的starter以spring-boot-starter-xxx
的方式命名的。官方建议自定义的starter使用xxx-spring-boot-starter
命名规则。以区分SpringBoot生态提供的starter。
新建一个工程
pom文件
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.itheima</groupId>
<artifactId>redis-spring-boot-autoconfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>redis-spring-boot-autoconfigure</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.3.0.RELEASE</spring-boot.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--引入jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
定义实体映射配置信息类
@ConfigurationProperties(prefix = "demo")
它可以把相同前缀的配置信息通过配置项名称映射成实体类,比如我们这里指定 prefix = “demo” 这样,我们就能将以demo为前缀的配置项拿到了。
ps:其实这个注解很强大,它不但能映射成String或基本类型的变量。还可以映射为List,Map等数据结构。
package com.itheima.redis.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@ConfigurationProperties(prefix = "redis")
public class RedisProperties {
private String host = "localhost";
private int port = 6379;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
}
定义配置类
这里,我们将DemoService类定义为一个Bean,交给Ioc容器。
-
@Configuration
注解就不多说了。 -
@EnableConfigurationProperties
注解。该注解是用来开启对3步骤中@ConfigurationProperties
注解配置Bean的支持。也就是@EnableConfigurationProperties
注解告诉Spring Boot 能支持@ConfigurationProperties
。当然了,也可以在@ConfigurationProperties
注解的类上添加@Configuration
或者@Component
注解 -
@ConditionalONClass
注解控制指定的Bean是否存在。简单来说也就是我们可以通过检测指定Bean是否存在类路径上,控制@Configuration
注解的配置类是否生效。
package com.itheima.redis.config;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
@Configuration
@EnableConfigurationProperties(RedisProperties.class)
@ConditionalOnClass(Jedis.class)
public class RedisAutoConfiguration {
/**
* 提供jedis的Bean
*/
@Bean
@ConditionalOnMissingBean(name = "jedis")
public Jedis jedis(RedisProperties redisProperties) {
System.out.println("RedisAutoConfiguration...");
return new Jedis(redisProperties.getHost(), redisProperties.getPort());
}
}
最重要的
如图,新建META-INF文件夹,然后创建spring.factories文件,
在该文件中加入如下配置,该配置指定上步骤中定义的配置类为自动装配的配置。
前面是固定的springboot自动装配类全包名,后面是配置类
测试工程引入配置工程starter测试
Springboot监听
springboot四个监听
- 自定义监听器的启动时机:MyApplicationRunner和MyCommandLineRunner都是当项目启动后执行,使用@Component放入容器即可使用
ApplicationRunner
MyApplicationRunner
/**
* 当项目启动后执行run方法。
*/
@Component
public class MyApplicationRunner implements ApplicationRunner {
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("ApplicationRunner...run");
System.out.println(Arrays.asList(args.getSourceArgs()));
}
}
CommandLineRunner
MyCommandLineRunner
@Component
public class MyCommandLineRunner implements CommandLineRunner {
@Override
public void run(String... args) throws Exception {
System.out.println("CommandLineRunner...run");
System.out.println(Arrays.asList(args));
}
}
ApplicationContextInitializer
MyApplicationContextInitializer的使用要在resource文件夹下添加META-INF/spring.factories
org.springframework.context.ApplicationContextInitializer=com.itheima.springbootlistener.listener.MyApplicationContextInitializer
@Component
public class MyApplicationContextInitializer implements ApplicationContextInitializer {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
System.out.println("ApplicationContextInitializer....initialize");
}
}
SpringApplicationRunListener
MySpringApplicationRunListener的使用要添加构造器
public class MySpringApplicationRunListener implements SpringApplicationRunListener {
public MySpringApplicationRunListener(SpringApplication application, String[] args) {
}
@Override
public void starting() {
System.out.println("starting...项目启动中");
}
@Override
public void environmentPrepared(ConfigurableEnvironment environment) {
System.out.println("environmentPrepared...环境对象开始准备");
}
@Override
public void contextPrepared(ConfigurableApplicationContext context) {
System.out.println("contextPrepared...上下文对象开始准备");
}
@Override
public void contextLoaded(ConfigurableApplicationContext context) {
System.out.println("contextLoaded...上下文对象开始加载");
}
@Override
public void started(ConfigurableApplicationContext context) {
System.out.println("started...上下文对象加载完成");
}
@Override
public void running(ConfigurableApplicationContext context) {
System.out.println("running...项目启动完成,开始运行");
}
@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
System.out.println("failed...项目启动失败");
}
}
SpringBoot流程分析-初始化
-
配置启动引导类(判断是否有启动主类)
-
判断是否是Web环境
-
获取初始化类、监听器类
SpringBoot流程分析-run**
-
启动计时器
-
执行监听器
-
准备环境
-
打印banner:可以resource下粘贴自定义的banner
-
创建context
refreshContext(context);
执行refreshContext方法后才真正创建Bean
Springboot监控
导入坐标
<dependency>
<groupld>org.springframework.boot</groupld>
<artifactld>spring-boot-starter-actuator</artifactld>
</dependency>
访问localhost:8080/actuator
Springboot项目部署
SpringBoot 项目开发完毕后,支持两种方式部署到服务器:
①jar包(官方推荐)
②war包
更改pom文件中的打包方式为war
修改启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
@SpringBootApplication
public class SpringbootDeployApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(SpringbootDeployApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(SpringbootDeployApplication.class);
}
}
指定打包的名称
<build>
<finalName>springboot</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
asset表 assetId ,assetSn assetName
department表 departmentName