七、Lombok中 @Slf4j 日志注解使用
@Slf4j可以简化日志的引入,用于代替以下这段代码
private static final Logger logger = LoggerFactory.getLogger(Xxx.class); 复制代码
上图中slf4j和commons-loggin都是日志规范;logback jdk-logging log4j log4j2都是日志实现。想要做到日志统一就需要用到桥接包,也可以参考SLF4J官网给出的解决方案
@Slf4j注解
首先添加相关的Jar包支持
<!-- 日志规范 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.36</version> </dependency> <!-- 日志实现 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> <scope>test</scope> </dependency> 复制代码
在test包中新建一个LogAnnotationTest测试类,使用@Slf4j注解
@Slf4j public class LogAnnotationTest { @Test public void testLogger(){ log.error("这是输出的日志信息"); } } 复制代码
执行testLogger方法
查看编译后的文件
自动帮我们生成了一个构造方法,并且定义了一个log属性,这个属性是slf4j的LoggerFactory通过调用getLogger方法返回的,并且通过接口来输出日志,这也是比较推荐的方法
八、对象创建 @Builder注解 与 @Singular注解
@Builder注解
@Builder注解的作用将对象的创建和使用完全分割开来,对象的创建只能用@Builder来创建,创建完成之后,对象不可变,可以使用这个对象,但是不能修改,这也符合高耦合低内聚的原则。
在test包下新建一个BuilderAnnotationTest测试类
@Builder @Data public class BuilderAnnotationTest { private static String staticField; private final String finalField; private final String initFinalField = "已经初始化的字段"; private String field; public static void main(String[] args) { // 创建BuilderAnnotationTest对象 // 首先调用builder方法创建一个可以链式赋值的对象 BuilderAnnotationTest builderAnnotationTest = BuilderAnnotationTest.builder() .finalField("手动赋值字段finalField") // 其他属性不能赋值 .field("手动赋值field") // 创建对象,此时创建的对象是不可变的 .build(); System.out.println(builderAnnotationTest); } } 复制代码
执行main方法
根据控制台的输出说明可以成功创建对象
查看target目录下编译后的代码
@Builder注解帮我们创建了一个构造方法
定义了一个builder方法来创建对象BuilderAnnotationTestBuilder 内部类
其中getter/setter/hashcode/equals方法都是@Data注解生成的
@Builder注解生成的内部类
这个类包含两个属性和一个空参构造方法,以及几个以属性名为方法名的方法,用于给属性赋值,还包含了toString方法以及build方法,build方法就是用于创建BuilderAnnotationTest对象的方法,使用了内部的两个属性,调用BuilderAnnotationTest上面的包含两个参数的构造方法来创建对象
总结下来就是创建一个内部类,用来持久化需要赋值的属性的属性值,并且使用这些属性通过调用构造方法来创建一个不可变的对象,对象创建过程对外是不可见的,所以对象是不可修改的
给普通属性赋值,再次调用main方法,查看创建出来的对象的普通属性的值是否会变化
普通属性的初始值创建对象的时候不会带过来;默认的值如果不手动赋值,是不会带过来的
@Singular注解
@Singular注解配合@Builder注解使用,可以简化集合类型的操作 给BuilderAnnotationTest类增加一个List列表属性,测试@Singular如何简化操作
private List<String> listFields; 复制代码
修改main方法,手动给list属性赋值
public static void main(String[] args) { // 创建BuilderAnnotationTest对象 // 首先调用builder方法创建一个可以链式赋值的对象 BuilderAnnotationTest builderAnnotationTest = BuilderAnnotationTest.builder() .finalField("手动赋值字段finalField") // 其他属性不能赋值 .field("手动赋值field") .listFields(new ArrayList<>()) // 创建对象,此时创建的对象是不可变的 .build(); 复制代码
执行main方法
列表属性上添加@Singular注解
@Singular private List<String> listFields; 复制代码
再次手动给列表属性赋值
有两个方法可以进行赋值
@Singular注解可以对集合属性生成单独追加单个元素的方法,并且可以连续追加。执行测试
listField方法赋值成功。也可以连续调用listField赋值多个元素到列表中
执行测试
说明连续调用赋值也是成功的
查看target目录下生成的class代码
listField方法可以接收一个单独的String类型参数,并将该参数加入到初始化号的listFields 中,相当于帮我们解决了集合为空的时候如何填入第一个元素
还生成了一个clearListFields方法,当集合不为空的时候清除集合
调用build方法的时候会判断集合是否为空,集合为空的时候会创建一个空的list赋值给集合属性,如果只有一个元素的时候,会创建一个singletonList赋值给列表,最后创建一个不可变的集合赋值给列表属性