springboot配置+日志+web
一、spring多模块开发优化
1.为什么需要?
idea中多模块开发,必须依赖于父亲模块,但是我们项目也必须是boot的parent,所以要在项目的父模块中管理boot的版本以来
2.怎么实现?
父级maven模块中:
<dependencyManagement>
<dependencies>
<!--springboot版本管理,springboot相关模块引入是就不需要制定版本了-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.0.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.多模块的打jar包支持
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>cn.itsource.springboot.HelloApplication</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
如果依赖父亲是spring-boot-starter-parent,就不需要添加,在里面已经配置了
</plugin>
</plugins>
</build>
二、spring boot配置
1.引入
前面我们看到访问的端口是8080,我们想把他改为9090,可以不,当然可以。在修改之前先学习一下关于配置文件的知识
2.配置文件类型-yml
SpringBoot使用一个全局的配置文件,配置文件名是固定的;
•application.properties -传统方式,不太优美
•application.yml-推荐使用
配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot在底层都给我们自动配置好;
YAML做配置一门语言:
以前的配置文件;大多都使用的是 xxxx.xml文件还有properties;
YAML:以数据为中心,比json、xml等更适合做配置文件;
YAML:配置例子
server:
port: 8081
XML:
<server>
<port>8081</port>
</server>
properties:
server.port =8081
3.YML语法
3.1.基本语法
k:(空格)v:表示一对键值对(空格必须有);
以空格的缩进来控制层级关系;只要是左对齐的一列数据,都是同一个层级的
server:
port: 8081
path: /hello
属性和值也是大小写敏感;
3.2.值的写法
1)字面量:普通的值(数字,字符串,布尔)
k: v:字面直接来写;
字符串默认不用加上单引号或者双引号;
"":双引号;不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
name: "zhangsan \n lisi":输出;zhangsan 换行 lisi
'':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据
name: ‘zhangsan \n lisi’:输出;zhangsan \n lisi
2)k: v:在下一行来写对象的属性和值的关系;注意缩进
对象还是k: v的方式
friends:
lastName: zhangsan
age: 20
3)数组(List、Set):
用- 值表示数组中的一个元素
pets:
- cat
- dog
- pig
4.读取配置文件
4.1.准备配置文件
server:
port: 80
student:
name: 小王
age: 20
boss: false
birth: 2017/12/12
maps: {k1: v1,k2: 12}
lists:
- zs
- ww
cat:
name: 猫科
age: 9
4.2.读取
关于两种方法的比较:
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;
@Component
//方式2:统一配置
//默认从application.yml或properties读取
//@ConfigurationProperties(prefix = "student")
@PropertySource(value={"classpath:person.properties"})
public class Student {
//取值方法一:@value(${xxx.yyy}),太繁琐
@Value("${student.name}")
private String name;
private Long age;
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> lists;
private Cat cat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public Boolean getBoss() {
return boss;
}
public void setBoss(Boolean boss) {
this.boss = boss;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
public Map<String, Object> getMaps() {
return maps;
}
public void setMaps(Map<String, Object> maps) {
this.maps = maps;
}
public List<Object> getLists() {
return lists;
}
public void setLists(List<Object> lists) {
this.lists = lists;
}
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", boss=" + boss +
", birth=" + birth +
", maps=" + maps +
", lists=" + lists +
", cat=" + cat +
'}';
}
}
读取指定配置文件:@PropertySource
@PropertySource(“classpath:指定配置文件”)
5.profile多环境支持
5.1.为什么要做多环境?
一套代码要在多种环境运行(开发,测试,上线),所以我们的配置文件要支持多种环境
5.2.多profile文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
application-dev.yml
application-test.yml
默认使用application.properties的配置;
5.3.Yml多文档块模式
server:
port: 80
---
server:
port: 8081
spring:
profiles:
active: prod
---
server:
port: 8083
spring:
profiles: dev
5.4.**特定环境
1、在配置文件中指定 spring.profiles.active=dev
2、命令行: 部署环境
java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod;
可以直接在测试的时候,配置传入命令行参数
3、虚拟机参数; 开发环境
-Dspring.profiles.active=dev
6.自动配置原理-怎么配置
解决怎么配置?
配置文件到底写什么?怎么写?
6.1.自动配置原理
1)SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration
2)@EnableAutoConfiguration 作用:
- 利用EnableAutoConfigurationImportSelector给容器中导入一些组件?
- 可以查看selectImports()方法的内容;
- List configurations = getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
将 类路径下 META-INF/spring.factories 里面配置的所有EnableAutoConfiguration的值加入到了容器中;
每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置;
每一个自动配置类进行自动配置功能;
3)以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理;
@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(HttpEncodingProperties.class) //启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication //Spring底层@Conditional注解(Spring注解版),根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效; 判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.class) //判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty(prefix = “spring.http.encoding”, value = “enabled”, matchIfMissing = true) //判断配置文件中是否存在某个配置 spring.http.encoding.enabled;如果不存在,判断也是成立的
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
//他已经和SpringBoot的配置文件映射了
private final HttpEncodingProperties properties;
//只有一个有参构造器的情况下,参数的值就会从容器中拿
public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
this.properties = properties;
}
@Bean //给容器中添加一个组件,这个组件的某些值需要从properties中获取
@ConditionalOnMissingBean(CharacterEncodingFilter.class) //判断容器没有这个组件?
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
return filter;
}
根据当前不同的条件判断,决定这个配置类是否生效?
一但这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
4)、所有在配置文件中能配置的属性都是在xxxxProperties类中封装者‘;配置文件能配置什么就可以参照某个功能对应的这个属性类
6.2.自动配置总结
精髓:
1)、SpringBoot启动会加载大量的自动配置类
2)、我们看我们需要的功能有没有SpringBoot默认写好的自动配置类;
3)、我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
4)、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值;
xxxxAutoConfigurartion:自动配置类;
给容器中添加组件
xxxxProperties:封装配置文件中相关属性;
使用SpringBoot;
1)、创建SpringBoot应用,选中我们需要的模块;
2)、SpringBoot已经默认将这些场景配置好了,只需要在配置文件中指定少量配置就可以运行起来
3)、自己编写业务代码;
三、整合测试-springboottest
1.导入spring-boot-starter-test
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
2.创建一个SpringBoot应用,并在下面创建一个Bean
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class);
}
}
@Controller
public class SpringBootController {
public void test(){
System.out.println("整合测试.....");
Date d=new Date();
System.out.println(d);
}
}
3.测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = App.class)//在哪里加载配置文件
public class TestSpringBoot {
@Autowired
private SpringBootController springBootController;
@Test
public void test(){
System.out.println(springBootController);
springBootController.test();
}
}
四、springboot日志支持
1.为什么需要日志框架?
通过日志的方式记录系统运行的过程或错误以便定位问题。
2.常见的日志框架
2.1.设计思想
1、System.out.println("");将关键数据打印在控制台;去掉?写在一个文件?
2、框架来记录系统的一些运行时信息;日志框架 ; zhanglogging.jar;log.ingo
3、高大上的几个功能?异步模式?自动归档?xxxx? zhanglogging-good.jar?
4、将以前框架卸下来?换上新的框架,重新修改之前相关的API;zhanglogging-prefect.jar;
5、JDBC---数据库驱动;
写了一个统一的接口层;日志门面(日志的一个抽象层);logging-abstract.jar;
给项目中导入具体的日志实现就行了;我们之前的日志框架都是实现的抽象层;
2.2.常见框架
3.Slf4j使用
遗留问题
统一日志记录,即使是别的框架和我一起统一使用slf4j进行输出?
解决办法:
1、将系统中其他日志框架先排除出去;
2、用中间包来替换原有的日志框架;
3、我们导入slf4j其他的实现
4.springboot日志关系
1)、SpringBoot底层也是使用slf4j+logback的方式进行日志记录
2)、SpringBoot也把其他的日志都替换成了slf4j;
3)、中间替换包?
4)、如果我们要引入其他框架,一定要把这个框架的默认日志依赖移除掉。
1 springboot底层使用了slf4j来作为门面,logback是默认实现
2 其他框架日志被替换或者转换
1)排除
2)转换或替换
3)导入slf4j,logbak
上面的事情都是spring帮我们做了,只需要关心两件事件就ok
1)默认logback有哪些配置
2)切换其他日志实现 log4j2
5.logback日志使用
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
–>
%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
修改配置
logging.level.cn.itsource=trace
#logging.path=
不指定路径在当前项目下生成springboot.log日志
可以指定完整的路径;
#logging.file=G:/springboot.log
在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
logging.path=/spring/log
在控制台输出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n
6.切换日志框架
五、SpringBoot web
1.入门-返回json
@Controller
@RequestMapping("/c01")
public class Controller01 {
//json字符串
@RequestMapping("/str")
@ResponseBody
public String jsonStr(){
return "webtest";
}
//json对象-日期特殊处理
@RequestMapping("/obj")
@ResponseBody
public Student jsonObj(){
return new Student(1L,"zs",new Date());
}
//json对象-日期特殊处理
@RequestMapping("/array")
@ResponseBody
public List<Student> jsonArray(){
return Arrays.asList(new Student(1L,"zs",new Date()),
new Student(2L,"ls",new Date()));
}
}
2.返回页面
2.1.常见的模板引擎
JSP、Velocity、Freemarker、Thymeleaf
2.2.Thymeleaf入门
引入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<properties>
<!--切换thymeleaf版本-->
<thymeleaf.version>3.0.9.RELEASE</thymeleaf.version>
<!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 -->
<!-- thymeleaf2 layout1-->
<thymeleaf-layout-dialect.version>2.2.2</thymeleaf-layout-dialect.version>
</properties>
使用:
@RestController
public class ThymeleafController {
@GetMapping("/hello")
public ModelAndView hello(Model model){
model.addAttribute("hello","你好.....");
return new ModelAndView("test");
}
}
<!DOCTYPE html>
<!--加入命名空间-->
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>模板入门</title>
<script th:src="@{/webjars/jquery/3.4.1/jquery.js}"></script>
<!--<script>-->
<!--alert($)-->
<!--</script>-->
</head>
<body>
<h1>成功</h1>
<!--使用语法th:text 将div里面的文本内容设置为 -->
<div th:text="${hello}">欢迎</div>
<img th:src="@{/ft.jpg}">
</body>
</html>
上一篇: 九条爆笑男女多娇雷语
下一篇: 梦想幽默节省祝福短信短信