做新应用就是这样,会遇到各种问题,昨天刚解决了加载某一个类时候抛出了
的问题,今天就有遇到了日志文件找不到的问题,还是和二方库有关的,下面就一一道来。
- class is not visible from class loader
- spring.application.name=spring-boot-demo-application
按照上面配置,运行后正常情况下我们希望在
目录应该有 applicaiton.log 日志文件,然而并没有,连
- user.home/spring-boot-demo-application/logs
这个文件夹都没有生成。
- spring-boot-demo-application
那么我们就去看看日志系统是如何查找并解析日志配置文件的,SpringBoot 中是使用 LoggingApplicationListener 这个类来进行日志系统的初始化的。LoggingApplicationListener 实现了 ApplicationListener 接口,那么我们通过时序图看 LoggingApplicationListener 的 onApplicationEvent 方法做了啥:
- protected String[] getStandardConfigLocations() {
- return new String[] { "logback-test.groovy", "logback-test.xml", "logback.groovy",
- "logback.xml" };
- }
像
这些是标准的。 那么具体怎么查找那,要看代码(10):
- "logback-test.groovy", "logback-test.xml", "logback.groovy","logback.xml"
- private String findConfig(String[] locations) {
- for (String location : locations) {
- ClassPathResource resource = new ClassPathResource(location,
- this.classLoader);
- if (resource.exists()) {
- return "classpath:" + location;
- }
- }
- return null;
- }
可知使用 ClassPathResource 类去查找,下面看 ClassPathResource 的 exists 方法:
- public boolean exists() {
- return (resolveURL() != null);
- }
- protected URL resolveURL() {
- if (this.clazz != null) {
- return this.clazz.getResource(this.path);
- }
- else if (this.classLoader != null) {
- return this.classLoader.getResource(this.path);
- }
- else {
- return ClassLoader.getSystemResource(this.path);
- }
- }
可知是使用
去查找这里 classLoader 为 AppClassloader。
- this.classLoader.getResource(this.path);
- protected String[] getSpringConfigLocations() {
- String[] locations = getStandardConfigLocations();
- for (int i = 0; i < locations.length; i++) {
- String extension = StringUtils.getFilenameExtension(locations[i]);
- locations[i] = locations[i].substring(0,
- locations[i].length() - extension.length() - 1) + "-spring."
- + extension;
- }
- return locations;
- }
可知是在 getStandardConfigLocations 的文件名上拼接 spring,拼接后的文件名为:
``` "logback-test-spring.groovy", "logback-test-spring.xml", "logback-spring.groovy","logback-spring.xml" ``
综上所述 SpringBoot 首先去查找标准的日志配置文件,如果找不到在去找拼接 Spring 的配置的文件。
那么上面我们说了应用中是引入了一个含有 logback.xml 的 jar 包,而这个 jar 包也是使用 appclassloader 加载的,所以在执行步骤(8)的时候找到了 jar 包里面的 logback.xml,所以就不会再去执行步骤(12)来找我们自定义的 logback-spring.xml 了。
日常开发中二方包里面不要带有日志配置文件,二方库中使用日志一般都是使用代码创建的方式。
来源: http://www.jianshu.com/p/80f32425f06d