学习项目笔记

/ 笔记 / 无站内评论 / 283浏览

前言

学习大佬写的项目,对一些优秀的用法学习学习

logger.isDebugEnabled()

先看下面的代码,在真正执行logger.debug()之前,进行了logger.isDebugEnabled()的判断,既然log4j.properties已经配置了log level为debug, 为什么还需要这个判断?

if (logger.isDebugEnabled()) { logger.debug("Entry number: " + i + " is " + entry[i].toString()); }

加上这个logger.isDebugEnabled() 后,如果值为false,if里面的代码就不会执行,就节省了字符串的拼接,少生成几个对象,如果不加,总会先拼接里面的字符串(连接字符串最好也不用+)

如果不用logger.isDebugEnabled(), 请使用log4j的其他重载的方法, 比如下面的

ogger.debug("Entry number: {} is {}", i, entry[i]);

这个代码实际上会先判断debug是否是enabled, 只有enabled才会format里面的字符串,下面就是log4j的源码:

@Override public void debug(final String message, final Supplier<?>... paramSuppliers) { logIfEnabled(FQCN, Level.DEBUG, null, message, paramSuppliers); }

<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">logIfEnabled</span><span class="hljs-params">(<span class="hljs-keyword">final</span> String fqcn, <span class="hljs-keyword">final</span> Level level, <span class="hljs-keyword">final</span> Marker marker, <span class="hljs-keyword">final</span> Message msg,
        <span class="hljs-keyword">final</span> Throwable t)</span> </span>{
    <span class="hljs-keyword">if</span> (isEnabled(level, marker, msg, t)) {
        logMessageSafely(fqcn, level, marker, msg, t);
    }
}

<span class="hljs-meta">@Override</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isEnabled</span><span class="hljs-params">(<span class="hljs-keyword">final</span> Level level, <span class="hljs-keyword">final</span> Marker marker, <span class="hljs-keyword">final</span> String message, <span class="hljs-keyword">final</span> Throwable t)</span> </span>{
    <span class="hljs-keyword">return</span> privateConfig.filter(level, marker, message, t);
}

一句话总结一下:logger.isDebugEnabled()为了提高某些情况下的性能才设计的。

@PostConstruct 注解

@PostConstruct是java5的时候引入的注解,指的是在项目启动的时候执行这个方法,也可以理解为在spring容器启动的时候执行,可作为一些数据的常规化加载,比如数据字典之类的。

####  1.@PostConstruct说明

     被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Serclet的inti()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。

#### 2.@PreConstruct说明

     被@PreConstruct修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreConstruct修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。


获取一个接口的所有实现类

 实现类加上Service注解,获取的时候直接@Resouce List<接口> 即可。

public interface IService {
int getName();
}

@Service
public class OneServiceImlp implements IService {
@Override
public int getName() {
return 1;
}
}

@Service
public class TwoServiceImlp implements IService {
@Override
public int getName() {
return 2;
}
}

Map<Integer, IService> map= Maps.newHashMap();

@Resource
private List<IService> iService;

//将所有实现类封装到map中,key为实现类getName值。可以使用一个枚举进行维护。

@RequestMapping("/imlp")
public String imlp() {
map=iService.stream().collect(Collectors.toMap(IService::getName, f -> f));
return JSON.toJSONString(map);
} 


常量应该封装到常量类,常量接口,还是枚举类中?


项目中大量用到了接口常量模式,网上搜集了一些资料。


首先,前两种可以看成是一样的。第一种写起来更方便一些吧,省去了public static final字段。但是如果从细想,接口可以被继承,可以将内容深入到其实现类代码中。这样对于一个常量类接口来说显然是不合理,但是你确实无法规避这个问题。唯一可以解决的办法就是弃用常量接口,选用常量类的方式。以final字段修饰,防止其被继承。并将其构造函数private化,防止被实例化。这显然在硬性上可以很好地解决这个问题。

但即便如此枚举任然是首选,但是如果不使用枚举的话,在《Effective Java》一书中,作者建议使用一般类加私有构造函数的方式。但是参考了 StackOverFlow 上大牛的讲解,我认为一般类上也应该再加上final字段。这样可以更好的避免一些不必要的麻烦。 


LinkedBlockingDeque

Java多线程之-LinkedBlockingDeque  将非常好





召唤蕾姆
琼ICP备18000156号

鄂公网安备 42011502000211号