SpringBoot (二) 日志入门、Web开发、Web自动配置原理

3 Log

3.1 简介

技术选型

  • 日志门面 (抽象层)
    • JCL 2014年最后更新
    • SLF4j (Simple Logging Facade for Java)
    • jboss-logging 天生不适合普通程序员用
  • 日志实现
    • JUL (java.util.logging) 生来只是怕垄断
    • Log4j
    • Log4j2 不同作者, 但太先进市场稍微小了点
    • Logback 与4j同一作者, 升级版

Spring框架默认是JCL, SpringBoot选用SLF4j + logback

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0hCXb3z3-1588083234244)(SpringBoot2.assets/image-20200426211024111.png)]

用logback还可以少一层

使用原则

  1. 不直接调用实现类, 而是调用抽象层;
  2. 配置文件还是按照"日志实现"来配置

HelloWorld

  1. 导入slf4j的jar和logback实现的jar

  2. 官方helloworld

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class HelloWorld {
         
      public static void main(String[] args) {
         
        Logger logger = LoggerFactory.getLogger(HelloWorld.class);
        logger.info("Hello World");
      }
    }
    

历史遗留日志的替换 (legacy)

  1. Spring(commons-logging) + Hibernate(jboss-logging) + MyBatis(xxx)

  2. 老系统不同组件可能不同日志工具

  3. 要统一日志, 即使别的框架也要统一使用slf4j

  4. 官方提供了replace的方案, 如下图. 用jcl-over-slf4j.jar来对commons logging API偷天换日

  5. “中间包"偷天换日的"先锋队”: jcl-over-slf4j.jar | log4j-over-slf4j.jar | jul-to-slf4j.jar

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uZhEp8wX-1588083234247)(SpringBoot2.assets/image-20200426225343662.png)]

具体如何统一到slf4j?

  1. 将系统中所有其它日志框架先排除出去
  2. 用 “中间包” 来替换原来的日志工具
  3. 导入slf4j的其他实现

3.2 Spring Boot 日志关系

SpringBoot能自动适配所有日志工具 (通过各种"中间包"), 自己底层用的是slf4j + logback的日志组合. 如果引入别的组件或者开发框架, 只需要把这个框架底层依赖的日志排除掉即可!

SpringBoot 的日志

SpringBoot日志依赖关系图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G4UG1wwv-1588083234248)(SpringBoot2.assets/image-20200426231806424.png)]

总结:

  • Spring Boot底层也是使用slf4j+logback的方式进行日志记录
  • Spring Boot也把其他日志替换成slf4j (还依赖三个"中间包")

spring boot底层如何替换其他框架?

利用"中间包", “偷梁换柱”

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OVzHds3m-1588083234251)(SpringBoot2.assets/image-20200426232753893.png)]

为什么称之为中间包, 偷梁换柱包? 代码片段演示

@SuppressWarnings("rawtypes")
public abstract class LogFactory {
   

    static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";
	// 它们底层有这一类的操作...把明明是slf4j的偷偷交给你用
    static LogFactory logFactory = new SLF4JLogFactory();

	//.....

如果引入其他软件开发框架

一定要把这个框架底层默认集成的日志依赖排除掉, Spring会自动也是借鉴了SpringBoot底层的操作:

...
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
...
  • <exclusions> - 排除

  • 注: commons logging是Spring默认的日志工具

3.4 日志使用

默认配置

  • 级别
  • 输出位置
  • 输出文件名

SpringBoot默认已经配置好了日志, 并且有一个默认日志级别, 称之为 root

package org.zhangcl.springboot;

import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;	// 注意这个包容易导错
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class SpringBoot03LoggingApplicationTests {
   

	// 日志"记录器"
	Logger logger = LoggerFactory.getLogger(this.getClass());
	@Test
	void contextLoads() {
   

		/*
		日志的"级别", 由低到高!
		可以调整需要输出的日志级别, 可以按级别选择性输出"某个级别以及更高级别"
		配置文件可以设置级别
		 */
		logger.trace("这是trace日志");
		logger.debug("这是debug日志");
		logger.info("这是info日志");
		logger.warn("这是warn日志");
		logger.error("这是error日志");
		/**
		 * 但是我这边更改配置没有用...
		 */
	}

}

也可以手动配置, 不过我这边按照视频讲解配置没有效果

# 日志级别
logging.level.org.zhangcl=error

# 如果不指定路径, 则在当前项目根目录下
logging.file=springboot.log
# 如果指定完整路径+文件名, 则按照执行 (我的只有重新运行项目主启动类才能)
logging.file=D:/springboot.log

#在当前磁盘的根路径下创建spirng文件夹和默认spring.log文件, linux就是绝对路径, win是c盘根目录
logging.path=/spring/log

# 控制台输出的格式
logging.pattern.console=
# 指定文件中日志输出格式
logging.pattern.file=

file 和 path的配合

logging.file logging.path Example description
n n 只在控制台输出
指定 n my.log 项目根目录输出my.log
n 指定 /var/log 指定位置: spring.log

指定配置

给类路径下放上每个日志框架各自的规定的配置文件即可

规则

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识别

    • 就可以使用高级特性: 某段配置只能在某个环境下生效
    <springProfile name="dev">...</springProfile>
    

3.5 切换框架

切换到log4j

  1. 在diagram图上剔除不要的: logback + log4j中间包
  2. 根据官网推荐再引入log4j-12, 底层自动也加入了log4j
  3. 再引入相关配置文件

切换到log4j2

根据boot官网, 需要和默认的starter-logging做二选一, 直接替换掉logging, 转而用starter-log4j2

4 Web

之前学的项目都是打jar包, 怎样web呢?

要解决的问题: (这一块内容可以删掉)

  • 如何导入静态资源
  • “首页”
  • 代替jsp: 模板引擎
  • 装配拓展SpringMVC
  • CRUD
  • 拦截器
  • 国际化: 中英文切换

4.1 静态资源映射规则

SpringMVC的相关配置都在WebMvcAutoconfiguration类中

ResourceProperties类

  • 可以设置与静态资源有关的属性, 比如缓存时间

    @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
    public class ResourceProperties implements ResourceLoaderAware {
         	// 这个类可以设置与静态资源有关的参数
    	// ...
    }
    

规则1: /webjars/**

webjars是什么

  • Web Libraries in Jars

  • 是一种把主流静态资源封装成jar形式的技术, 比如jQuery.js文件一般是以静态资源导入, 但这里以依赖jar的方式封装一下给我们用,的一种技术

  • 官网给出最流行的几个例子:

    image-20200427121026978

源码分析

  • idea中搜索WebMvcAutoconfiguration类找到其中的这个方法, 截取如下:
		@Override
		public void addResourceHandlers(ResourceHandlerRegistry registry) {
   
			if (!this.resourceProperties.isAddMappings()) {
   
				logger.debug("Default resource handling disabled");
				return;
			}
			Integer cachePeriod = this.resourceProperties.getCachePeriod();
			if (!registry.hasMappingForPattern("/webjars/**")) {
   
				customizeResourceHandlerRegistration(
						registry.addResourceHandler("/webjars/**")
								.addResourceLocations(
										"classpath:/META-INF/resources/webjars/")
						.setCachePeriod(cachePeriod));
			}
			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
			if (!registry.hasMappingForPattern(staticPathPattern)) {
   
				customizeResourceHandlerRegistration(
						registry.addResourceHandler(staticPathPattern)
								.addResourceLocations(
										this.resourceProperties.getStaticLocations())
						.setCachePeriod(cachePeriod));
			}
		}
  • 符合/webjars/**的, 会去这个位置找资源addResourceLocations("classpath:/META-INF/resources/webjars/"

例子

  1. 我们以jQuery为例, 在webjars官网选择版本, maven方式, 通过maven引入后, 在依赖列表:

    意味着: 我们的classpath:/webjars下有东西了

image-20200427123600281
  1. 发现了代码中描述的路径
  2. 测试: 请求localhost:8080/webjars/jquery/3.3.1/jquery.js , 可以打开.

规则2: 静态资源的文件夹

注: 正常情况下静态资源是不允许外部直接访问的!

  1. classpath:/META-INF/resources/

  2. classpath:/resources/

  3. classpath:/static/

  4. classpath:/public/

  5. 当前项目根路径(个人自己测试不行, 反正也是优先级最低, 不管了)

localhost:8080/

规则3: 欢迎页

  • 默认指定文件名: index.html

  • 默认位置: (如规则2)

  • 默认url:localhost:8080/, 第层已经映射好了, 记住这个就行

规则4: 网页图标

所有的: **/favicon.ico 都在静态资源文件下找

(个人不重视 不熟练)

自定义: 静态资源路径

原则

如果自定义, 则默认的会失效

如何定义?

操作application.properties中设置:

spring.resources.static-locations=classpath:/mylocation1/,classpath:/mylocation2/deep1/
  • 优先级: 按照以上写入顺序
  • /mylocation2/deep1中, 个人测试了mylocation2目录, 无效

4.2 模板引擎

  • 市面上: JSP | Velocity | Freemarker | Thymeleaf

  • 重点讲SB推荐的Thymeleaf

    • 语法简单\功能强大
  • 如果要识别在template目录下静态资源, 除了Controller, 额外还需要模板引擎支持, 比如Thymeleaf

使用 - 基本规则

依赖 (引用为准)

<properties></
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值