实际
2020-04-20 10:37:42
此篇文章使用版本:2.2.2.RELEASE
SpringBoot 入门
简介
1 | SpringBoot |
HelloWorld 实现&分析
功能:浏览器发送hello请求,服务器接受请求并处理,响应Hello World字符串;
- 实现
- 分析
①pom文件
②主程序类,主入口类【分析注解@SpringBootApplication & 自动化加载配置类】
Spring Initializer
IDE都支持使用Spring的项目创建向导快速创建一个SpringBoot项目;
选择我们需要的模块;向导会联网创建SpringBoot项目;
默认生成的SpringBoot项目;
- 主程序已经生成好了,我们只需要我们自己的逻辑
- resources文件夹中目录结构
- static:保存所有的静态资源; js css images;
- templates:保存所有的模板页面;(SpringBoot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面);可以使用模板引擎(freemarker、thymeleaf);
- application.properties:SpringBoot应用的配置文件;可以修改一些默认设置;
SpringBoot配置
properties和yml
SpringBoot使用一个全局的配置文件,配置文件名是固定的;application.properties
application.yml
配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;
1 | YAML(YAML Ain't Markup Language) |
- 语法 + 单/双引号区别 + 中文编码问题
@Configuration
【对@Component的一种封装,用于替代之前的xml配置文件形式】
@ConfigurationProperties
注入数据的两种使用方式【@EnableConfigurationProperties注解的使用】
配置文件数据校验 + 配置文件代码提示(需重启主配置类)
可以选择设置【关闭通知面板】
@Value
注意:这个可以没有对应的set方法也可以注入
- @Value获取值和@ConfigurationProperties获取值比较
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入 | 单个注入 |
松散绑定(松散语法) | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
配置文件yml还是properties他们都能获取到值;
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
@PropertySource
@ImportResource
- 使用方法
- SpringBoot推荐使用@Configuration
配置文件占位符
三种激活方式
@ActiveProfiles
此注解的效果同指定虚拟机参数。@ActiveProfiles("dev")
等同于 -Dspring.profiles.active=dev
区别在于:此注解是专门用于测试使用。不能给主配置类使用。
@Profile
官网说了,只能作用于@Component
@Configuration
@ConfigurationProperties
标记的类上,或被标记类的方法中。
注意:启动主配置类时要使用三种方式激活对应的文件。测试时可使用@ActiveProfiles
进行激活。
加载顺序
我的理解:先加载的会覆盖后加载的,这些配置文件呢,是为了覆盖默认的自动化配置。
会形成互补配置。
1 | 指定以下参数 启动主配置类 |
加载位置
我这里测试版本是:2.2.2.RELEASE
(可能会和1.x.x不一样)
【下面的加载顺序会形成互补配置】
①只有test.properties配置文件生效【其他四个地方全失效】java -jar .\spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=D:/test.properties
②还会加载那四个位置,但test.properties中的内容会赋值已有的内容(相当于它比那四个位置加载优先级还要高)java -jar .\spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.additional-location=D:/test.properties
外部化配置加载顺序
自动配置原理
在上面我们已经讲到了主入口类注解@SpringBootApplication
会加载自动化配置类,文件位置:spring-boot-autoconfigure-2.2.2.RELEASE.jar!\META-INF\spring.factories
可参考HelloWorld分析-主程序类,主入口类注解@SpringBootApplication
下面我们来分析一下自动配置的原理
2.2.2.RELEASE官方文档理解自定义配置(@Conditional注解)
SpringBoot的精髓:
1 | 1、SpringBoot启动会加载大量的自动配置类 |
xxxxAutoConfigurartion:自动配置类;,给容器中添加组件,xxxxProperties:封装配置文件中相关属性;
@Conditional派生注解
可参考2.2.2.RELEASE官方文档理解自定义配置(@Conditional派生注解)
作用:必须是@Conditional
指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效;
@Conditional扩展注解 | 作用(判断是否满足当前指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定Bean; |
@ConditionalOnMissingBean | 容器中不存在指定Bean;(与@Bean一起使用作用于方法返回值,不存在Bean才进入方法) |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 系统中没有指定的类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是web环境 |
@ConditionalOnJndi | JNDI存在指定项 |
自动配置类必须在一定的条件下才能生效;,我们怎么知道哪些自动配置类生效;
==我们可以通过启用 debug=true属性(或使用命令行参数java -jar xxx.jar –debug=true);来让控制台打印自动配置报告==
日志
日志框架
一个故事概括
1
2
3
4
5
6
7
8小张;开发一个大型系统;
1、System.out.println("");将关键数据打印在控制台;去掉?写在一个文件?
2、框架来记录系统的一些运行时信息;日志框架 ; zhanglogging.jar;
3、高大上的几个功能?异步模式?自动归档?xxxx? zhanglogging-good.jar?
4、将以前框架卸下来?换上新的框架,重新修改之前相关的API;zhanglogging-prefect.jar;
5、JDBC---数据库驱动;
写了一个统一的接口层;日志门面(日志的一个抽象层);logging-abstract.jar;
给项目中导入具体的日志实现就行了;我们之前的日志框架都是实现的抽象层;市面上的日志框架;
1
2
3
4
5
6
7
8
9日志门面(日志的抽象层)- Interface
JCL(Jakarta Commons Logging)
SLF4j(Simple Logging Facade for Java)
jboss-logging(只有Hibernate在用)
日志实现 - implements
Log4j(有点垃圾)
JUL(java.util.logging)
Log4j2(太新了)
Logback选一个(抽象层)和 一个实现; 【SLF4J + Logback】
SpringBoot:底层是Spring框架,Spring框架默认是用JCL;
==SpringBoot选用 SLF4j和logback;==
SpringBoot日志关系
场景启动器
1 | <dependency> |
SpringBoot使用【日志场景启动器】来做日志功能;
1 | <dependency> |
总结:
1)、SpringBoot底层也是使用slf4j+logback的方式进行日志记录
2)、SpringBoot也把其他的日志都替换成了slf4j;
3)、中间替换包?
1 | "rawtypes") ( |
4)、如果我们要引入其他框架?一定要把这个框架的默认日志依赖移除掉?
Spring框架用的是commons-logging;
1 | <dependency> |
==SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时,需要把这个框架依赖排除掉即可;==
日志使用
默认配置
SpringBoot默认帮我们配置好了日志;
1 | 日期和时间:毫秒精度,易于排序。 |
SpringBoot修改日志的默认配置
1 | trace = |
日志输出格式:
1 | %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n |
logging.file | logging.path | Example | Description |
---|---|---|---|
(none) | (none) | 只在控制台输出 | |
指定文件名 | (none) | my.log | 输出日志到my.log文件 |
(none) | 指定目录 | /var/log | 输出到指定目录的 spring.log 文件中 |
指定配置
给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了
Logging System | Customization |
---|---|
Logback | logback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) | logging.properties |
logback.xml:直接就被日志框架识别了;
logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能
1 | <springProfile name="staging"> |
如:
1 | <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> |
如果使用logback.xml作为日志配置文件,还要使用profile功能,会有错误no applicable action for [springProfile]
切换日志框架
可以按照slf4j的日志适配图,进行相关的切换;
slf4j+log4j的方式;1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>logback-classic</artifactId>
<groupId>ch.qos.logback</groupId>
</exclusion>
<exclusion>
<artifactId>log4j-over-slf4j</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</dependency>切换为log4j2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>