文章目录

  • 介绍
  • 引入Maven依赖
  • 常用的注解
    • @NoArgsConstructor/@AllArgsConstructor
    • @RequiredArgsConstructor
    • @Getter/@Setter
    • @ToString/@EqualsAndHashCode
    • @Data
    • @Builder
    • @Accessors
  • 其他注解
    • @SneakyThrows
    • @Value
    • @Cleanup
    • @NotNull
    • @Synchronized
    • @Log、@Log4j、@Slf4j、@Log4j2、@CommonsLog、@XSlf4j等日志注解
      • @Log注解
      • @Log4j注解
      • @Log4j2注解
      • @Slf4j注解
    • @Delegate
    • @Singular

介绍

官方网址 : https://projectlombok.org/

Lombok是一款Java开发插件,使得Java开发者可以通过其定义的一些注解来消除业务工程中冗长和繁琐的代码,尤其对于简单的Java模型对象(POJO)。

在开发环境中使用Lombok插件后,Java开发人员可以节省出重复构建,诸如hashCode和equals这样的方法以及各种业务对象模型的accessor和ToString等方法的大量时间。对于这些方法,它能够在编译源代码期间自动帮我们生成这些方法,并没有如反射那样降低程序的性能。

引入Maven依赖

采用最新版本 1.18.24

<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope><version>1.18.24</version>
</dependency>

常用的注解

@NoArgsConstructor/@AllArgsConstructor

  • @NoArgsConstructor/@AllArgsConstructor就是为该类产生无参的构造方法和包含所有参数的构造方法

测试案例1:

@AllArgsConstructor
public class Demo extends Parent{private String name;private int age;
}@AllArgsConstructor
@NoArgsConstructor
class Parent {private Integer id;
}

编译后的两个class文件如下:

此注解并不会把父类的属性id拿到Demo的构造器里面去,这是需要注意的地方。

public class Demo {private String name;private int age;public Demo() {}public Demo(String name, int age) {this.name = name;this.age = age;}
}class Parent {private Integer id;public Parent(Integer id) {this.id = id;}public Parent() {}
}

通过IDEA的类结构, 也可以看出来生成了哪些东西


测试案例2:

通过 @AllArgsConstructor(access = AccessLevel.PROTECTED) , 可以指定构造器的访问权限

@AllArgsConstructor(access = AccessLevel.PROTECTED)
public class Demo{private String name;private int age;
}

编译后生成:

public class Demo {private String name;private int age;protected Demo(String name, int age) {this.name = name;this.age = age;}
}

测试案例3:

@AllArgsConstructor(access = AccessLevel.PROTECTED, staticName = “test”)

@AllArgsConstructor(access = AccessLevel.PROTECTED, staticName = "test")
public class Demo{private final int finalVal = 10;private String name;private int age;
}

编译后 :

public class Demo {private String name;private int age;private Demo(String name, int age) {this.name = name;this.age = age;}protected static Demo test(String name, int age) {return new Demo(name, age);}
}

上面效果为:可以指定生成的构造器的访问权限。但是如果指定了一个静态方法,那么构造器会自动会被private,只通过静态方法对外提供访问,并且我们发现final的属性值,是不会放进构造函数里面的。

@NoArgsConstructor的使用方式同@AllArgsConstructor

@RequiredArgsConstructor

@RequiredArgsConstructor注解则会将类中所有带有@NonNull注解 / org.jetbrains.annotations.NotNull注解的或者带有final修饰的成员变量生成对应的构造方法

测试案例:

@RequiredArgsConstructor
public class Demo {@NonNullprivate final int finalVal;@NonNullprivate String name;@NonNullprivate int age;
}

编译后生成:

import lombok.NonNull;public class Demo {@NonNullprivate final int finalVal;@NonNullprivate String name;@NonNullprivate int age;public Demo(@NonNull int finalVal, @NonNull String name, @NonNull int age) {if (name == null) {throw new NullPointerException("name is marked non-null but is null");} else {this.finalVal = finalVal;this.name = name;this.age = age;}}
}


解释:该注解会识别@NonNull字段和final修饰得字段,然后以该字段为元素生成一个构造函数。

如果所有字段都没有@NonNull注解,那效果同@NoArgsConstructor ;
@RequiredArgsConstructor 注解的参数, 和其他两个注解一样

注意: 当然这三个生成构造器的注解,要求成员变量都是非静态的, 否则静态变量不会在构造器中被赋值

@Getter/@Setter

这一对注解从名字上就很好理解,用在成员变量上面或者类上面,相当于为成员变量生成对应的get和set方法,同时还可以为生成的方法指定访问修饰符,当然,默认为public

// 如果指定在类上,所有字段都会生成get/set方法
// 指定在字段上, 只有标注的字段才会生成get/set方法
@Getter
@Setter
public class Demo {private String name;private int age;
}

这两个注解直接用在类上,可以为此类里的所有非静态成员变量生成对应的get和set方法。如果是final变量,那就只会有get方法

@ToString/@EqualsAndHashCode

这两个注解也比较好理解,就是生成toString,equals和hashcode方法,同时后者还会生成一个canEqual方法,用于判断某个对象是否是当前类的实例。生成方法时只会使用类中的非静态成员变量。

@ToString
@EqualsAndHashCode
public class Demo {private String name;private int age;
}

有些关键的属性,可以控制toString的输出,我们可以了解一下:

//@EqualsAndHashCode也有类似的下面的属性,
@ToString(includeFieldNames = true, //是否使用字段名exclude = {"name"}, //排除某些字段of = {"age"}, //只使用某些字段callSuper = true //是否让父类字段也参与 默认false
)

@Data

相当于注解集合。效果等同于 @Getter + @Setter + @ToString + @EqualsAndHashCode + @RequiredArgsConstructor 效果同和这5个注解的效果

需要注意的是,这里不包括@NoArgsConstructor和@AllArgsConstructor

  • 所以, 一般使用@Data时,要配合这两个注解一起使用
@Data
public class Demo {private String name;private int age;
}

@Builder

@Builder提供了一种比较推崇的构建值对象的方式; 非常推荐的一种构建值对象的方式。

缺点就是父类的属性不能产于builder

标注@Builder的类, 会在类内部生成一个内部类,用于生成值对象

@Builder
public class Demo {private final int finalVal = 10;private String name;private int age;
}

编译后生成:

public class Demo {private final int finalVal = 10;private String name;private int age;Demo(String name, int age) {this.name = name;this.age = age;}public static Demo.DemoBuilder builder() {return new Demo.DemoBuilder();}public static class DemoBuilder {private String name;private int age;DemoBuilder() {}public Demo.DemoBuilder name(String name) {this.name = name;return this;}public Demo.DemoBuilder age(int age) {this.age = age;return this;}public Demo build() {return new Demo(this.name, this.age);}public String toString() {return "Demo.DemoBuilder(name=" + this.name + ", age=" + this.age + ")";}}
}


使用方式:

public class Main {public static void main(String[] args) {Demo demo = Demo.builder().name("zss").age(20).build();System.out.println(demo);}
}

一般我们给POJO类, 标注的Lombok注解, 百分之90就是这4个 : @Data, @NoArgsConstructor, @AllArgsConstructor, @Builder

@Accessors

@Accessors 一个为getter和setter方法设计的更流畅的注解
这个注解要搭配@Getter与@Setter使用,用来修改默认的setter与getter方法的形式。

@Accessors属性详解

  • fluent 属性 : 链式的形式 这个特别好用,方法连缀越来越方便了
  • chain 属性 : 流式的形式(若无显示指定chain的值,也会把chain设置为true)
  • prefix 属性 : 生成指定前缀的属性的getter与setter方法,并且生成的getter与setter方法时会去除前缀

测试不使用@Accessors时

fluent属性

默认为false,当该值为 true 时,对应字段的 getter 方法前面就没有 get,setter 方法就不会有 set。

编译后生成:

public class Demo {private final int finalVal = 10;private String xxName;private int yyAge;public Demo() {}public int finalVal() {Objects.requireNonNull(this);return 10;}public String xxName() {return this.xxName;}public int yyAge() {return this.yyAge;}public Demo xxName(String xxName) {this.xxName = xxName;return this;}public Demo yyAge(int yyAge) {this.yyAge = yyAge;return this;}public String toString() {int var10000 = this.finalVal();return "Demo(finalVal=" + var10000 + ", xxName=" + this.xxName() + ", yyAge=" + this.yyAge() + ")";}
}

使用:

public class Main {public static void main(String[] args) {Demo demo = new Demo();// setter方法; 这里包含了chain=true的功能,可以链式设置值demo.xxName("lucky").yyAge(20);// getter方法System.out.println(demo.xxName() + "," + demo.yyAge());System.out.println("demo = " + demo);}
}

chain属性

不写默认为false,当该值为 true 时,对应字段的 setter 方法调用后,会返回当前对象, 进行链式设置值


编译后生成:

public class Demo {private final int finalVal = 10;private String xxName;private int yyAge;public Demo() {}public int getFinalVal() {Objects.requireNonNull(this);return 10;}public String getXxName() {return this.xxName;}public int getYyAge() {return this.yyAge;}public Demo setXxName(String xxName) {this.xxName = xxName;return this;}public Demo setYyAge(int yyAge) {this.yyAge = yyAge;return this;}public String toString() {int var10000 = this.getFinalVal();return "Demo(finalVal=" + var10000 + ", xxName=" + this.getXxName() + ", yyAge=" + this.getYyAge() + ")";}
}

使用

public class Main {public static void main(String[] args) {Demo demo = new Demo();// setter方法demo.setXxName("lucky").setYyAge(20);System.out.println("demo = " + demo);}
}

prefix属性

该属性是一个字符串数组,当该数组有值时,表示忽略字段中对应的前缀,生成对应的 getter 和 setter 方法。

如果,我们把它的前缀加到 @Accessors 的属性值中,则可以像没有前缀那样,去调用字段的 getter和 setter 方法。

这里只是把原有属性的前缀给去掉

其他注解

@SneakyThrows

这个注解用在方法上,可以将方法中的代码用try-catch语句包裹起来,捕获异常并在catch中用Lombok.sneakyThrow(e)把异常抛出,可以使用@SneakyThrows(Exception.class)的形式指定抛出哪种异常

public class Demo {@SneakyThrows(UnsupportedEncodingException.class)public String utf8ToString(byte[] bytes) {return new String(bytes, "UTF8");}
}

编译生成后:

public class Demo {public String utf8ToString(byte[] bytes) {try {return new String(bytes, "UTF8");} catch (UnsupportedEncodingException var3) {throw var3;}}
}

@Value

@Value注解和@Data类似,区别在于它会把所有成员变量默认定义为private final修饰,并且不会生成set方法。

所以@Value更适合只读性更强的类,所以特殊情况下,还是可以使用的。

@Cleanup

@Cleanup能够自动释放资源; 和 try-with-resources的区别: try-with-resources和lombok的@Cleanup

这个注解用在局部变量上,可以保证此变量代表的资源会被自动关闭,默认是调用资源的close()方法。

如果该资源有其它关闭方法,可使用@Cleanup(“methodName”)来指定要调用的方法,就用输入输出流来举个例子吧:

@SneakyThrows(Exception.class)
public static void main(String[] args) {@Cleanup InputStream in = new FileInputStream(args[0]);@Cleanup OutputStream out = new FileOutputStream(args[1]);byte[] b = new byte[1024];while (true) {int r = in.read(b);if (r == -1) break;out.write(b, 0, r);}
}

编译后生成:

public static void main(String[] args) {try {FileInputStream in = new FileInputStream(args[0]);try {FileOutputStream out = new FileOutputStream(args[1]);try {byte[] b = new byte[1024];while(true) {int r = in.read(b);if (r == -1) {return;}out.write(b, 0, r);}} finally {if (Collections.singletonList(out).get(0) != null) {out.close();}}} finally {if (Collections.singletonList(in).get(0) != null) {in.close();}}} catch (Exception var15) {throw var15;}
}

@NotNull

这个注解可以用在成员方法或者构造方法的参数上,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常。

//成员方法参数加上@NonNull注解
public String getName(@NonNull Person p){return p.getName();
}

编译生成后:

public String getName(@NonNull Person p){if(p == null){throw new NullPointerException("person");}return p.getName();
}

@Synchronized

作用于方法,可以替换 synchronized 关键字或 lock 锁

这个注解用在类方法或者实例方法上,效果和synchronized关键字相同,区别在于锁对象不同,对于类方法和实例方法,synchronized关键字的锁对象分别是类的class对象和this对象

而@Synchronized得锁对象分别是私有静态final对象lock和私有final对象lock,当然,也可以自己指定锁对象

注意: 属性value指定锁对象,当锁对象不存在时,则编译不通过,默认为 “”

public class Demo {private Object obj;@Synchronizedpublic static void hello() {System.out.println("world");}@Synchronizedpublic int answerToLife() {return 42;}@Synchronized("obj")public void foo() {System.out.println("bar");}
}

编译后生成:

public class Demo {private static final Object $LOCK = new Object[0];private final Object $lock = new Object[0];private Object obj;public Demo() {}public static void hello() {synchronized($LOCK) {System.out.println("world");}}public int answerToLife() {synchronized(this.$lock) {return 42;}}public void foo() {synchronized(this.obj) {System.out.println("bar");}}
}

@Log、@Log4j、@Slf4j、@Log4j2、@CommonsLog、@XSlf4j等日志注解

相对日志进行了解的, 请参考我的博客 : 日志系列

这些注解都有topic属性:设置 getLogger(String name) 方法的参数

这些注解用在类上,可以省去从日志工厂生成日志对象这一步,直接进行日志记录。

具体注解根据日志工具的不同而不同,同时,可以在注解中使用topic来指定生成log对象时的类名。不同的日志注解总结如下(上面是注解,下面是实际作用):

@Log注解

默认是会生成java.util.logging.Logger对象, JUL

private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());

使用JUL日志框架

@Log
public class LombokJULTest {/*日志入口程序java.util.logging.Logger*/// @Log标注在JULTest类上,就表示自动生成了下面这行代码// Logger log = Logger.getLogger("com.lucky.jul.JULTest");@Testpublic void test01() {// 方式1log.info("输出info信息1");// 方式2log.log(Level.INFO, "输出info信息2");}
}控制台输出:
八月 14, 2022 9:17:13 上午 com.lucky.jul.JULTest test01
信息: 输出info信息1
八月 14, 2022 9:17:13 上午 com.lucky.jul.JULTest test01
信息: 输出info信息2

编译后生成:

public class LombokJULTest {private static final Logger log = Logger.getLogger(LombokJULTest.class.getName());public LombokJULTest() {}@Testpublic void testLombokLog() {log.info("输出info信息1");log.log(Level.INFO, "输出info信息2");}
}

@Log4j注解

默认是会生成 org.apache.log4j.Logger 对象

private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(LogExample.class);

使用Log4j框架案例:

<dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.17</version>
</dependency>

log4j配置文件 (resources下, log4j.properties文件)

log4j.rootLogger=trace,console,
#配置appender输出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#配置输出的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-5p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n
@Log4j
public class LombokLog4jTest {// 使用Lombok的@Log4j注解, 相当于会自动生成下面这个logger对象// Logger log = Logger.getLogger(LombokLog4jTest.class);@Testpublic void testLombokLog4j() {// BasicConfigurator.configure(); // 默认指定了log4j的logger,输出位置,输出格式;不需要配置文件也可以打印日志// debug是默认的级别, 所以不会输出trace信息log.fatal("fatal信息");log.error("error信息");log.warn("warn信息");log.info("info信息");log.debug("debug信息");log.trace("trace信息");}
}控制台输出:
[FATAL]0 com.lucky.log4j.LombokLog4jTestmain2022-08-14 11:02:45:720 fatal信息
[ERROR]2 com.lucky.log4j.LombokLog4jTestmain2022-08-14 11:02:45:722 error信息
[WARN ]2 com.lucky.log4j.LombokLog4jTestmain2022-08-14 11:02:45:722 warn信息
[INFO ]3 com.lucky.log4j.LombokLog4jTestmain2022-08-14 11:02:45:723 info信息

编译后生成代码:

public class LombokLog4jTest {private static final Logger log = Logger.getLogger(LombokLog4jTest.class);public LombokLog4jTest() {}@Testpublic void testLombokLog4j() {log.fatal("fatal信息");log.error("error信息");log.warn("warn信息");log.info("info信息");log.debug("debug信息");log.trace("trace信息");}
}

@Log4j2注解

前最优秀的Java日志框架, Log4j2也可以充当简单的日志门面来使用

private static final org.apache.logging.log4j.Logger log = org.apache.logging.log4j.LogManager.getLogger(LogExample.class);

使用案例: (本次使用Log4j2充当日志门面,实现简单的日志打印)

<dependencies><!-- log4j2日志门面 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.12.1</version></dependency><!-- log4j2日志实现 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.12.1</version></dependency><!-- 异步日志依赖 --><dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.3.7</version></dependency>
</dependencies>

resources目录下, log4j2.xml

<?xml version="1.0" encoding="utf-8" ?>
<Configuration status="debug"><!-- 配置appender --><Appenders><Console name="consoleAppender" target="SYSTEM_ERR"><PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"/></Console></Appenders><!-- 配置logger --><Loggers><!-- 配置root logger --><Root level="trace"><!-- 引用appender --><AppenderRef ref="consoleAppender"/></Root></Loggers>
</Configuration>
import lombok.extern.log4j.Log4j2;
import org.junit.Test;@Log4j2
public class LombokLog4j2Test {// @Log4j2会自动生成下面的Logger对象// Logger log = LogManager.getLogger(Log4j2Test.class);@Testpublic void lombokLog4jTest() {log.fatal("fatal信息");log.error("error信息");log.warn("warn信息");log.info("info信息");log.debug("debug信息");log.trace("trace信息");}
}控制台输出:
[FATAL] 2022-08-14 11:43:31.845 com.lucky.Log4j2Test lombokLog4jTest 14 main fatal信息
[ERROR] 2022-08-14 11:43:31.849 com.lucky.Log4j2Test lombokLog4jTest 15 main error信息
[WARN ] 2022-08-14 11:43:31.849 com.lucky.Log4j2Test lombokLog4jTest 16 main warn信息
[INFO ] 2022-08-14 11:43:31.849 com.lucky.Log4j2Test lombokLog4jTest 17 main info信息
[DEBUG] 2022-08-14 11:43:31.850 com.lucky.Log4j2Test lombokLog4jTest 18 main debug信息
[TRACE] 2022-08-14 11:43:31.850 com.lucky.Log4j2Test lombokLog4jTest 19 main trace信息

编译后生成:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.Test;public class LombokLog4j2Test {private static final Logger log = LogManager.getLogger(LombokLog4j2Test.class);public LombokLog4j2Test() {}@Testpublic void lombokLog4jTest() {log.fatal("fatal信息");log.error("error信息");log.warn("warn信息");log.info("info信息");log.debug("debug信息");log.trace("trace信息");}
}

@Slf4j注解

Slf4j日志门面(Simple Logging Facade For Java) , Slf4j主要是为了给Java日志访问提供一套标准、规范的API框架,其主要意义在于提供接口,具体的实现可以交由其他日志框架,例如log4j和logback等

private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(LogExample.class);

使用案例: (Slf4j + Log4j2实现日志输出)

<!-- slf4j日志门面 -->
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version>
</dependency>
<!-- log4j2适配器 -->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.12.1</version>
</dependency><!-- log4j2日志门面 -->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.12.1</version>
</dependency><!-- log4j2日志实现 -->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.12.1</version>
</dependency><!-- 异步日志依赖 -->
<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.3.7</version>
</dependency>

resources目录下, log4j2.xml

<?xml version="1.0" encoding="utf-8" ?>
<Configuration status="debug"><!-- 配置appender --><Appenders><Console name="consoleAppender" target="SYSTEM_ERR"><PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %c %M %L %thread %m%n"/></Console></Appenders><!-- 配置logger --><Loggers><!-- 配置root logger --><Root level="trace"><!-- 引用appender --><AppenderRef ref="consoleAppender"/></Root></Loggers>
</Configuration>
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;@Slf4j
public class LombokSlf4jTest {// @Slf4j会自动生成下面这个Logger对象// Logger log = LoggerFactory.getLogger(LombokSlf4jTest.class);@Testpublic void lombokSlf4jTest() {log.error("error信息");log.warn("warn信息");log.info("info信息");log.debug("debug信息");log.trace("trace信息");}
}

编译后生成:

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LombokSlf4jTest {private static final Logger log = LoggerFactory.getLogger(LombokSlf4jTest.class);public LombokSlf4jTest() {}@Testpublic void lombokSlf4jTest() {log.error("error信息");log.warn("warn信息");log.info("info信息");log.debug("debug信息");log.trace("trace信息");}
}

其他的Lombok日志注解, 自行了解咯

@CommonsLog
private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog(LogExample.class);
@JBossLog
private static final org.jboss.logging.Logger log = org.jboss.logging.Logger.getLogger(LogExample.class);
@XSlf4j
private static final org.slf4j.ext.XLogger log = org.slf4j.ext.XLoggerFactory.getXLogger(LogExample.class);

@Delegate

被@Delegate注释的属性,会把这个属性类型的公有非静态方法合到当前类

public class Person {public void personMsg() {System.out.println("Person.personMsg");}public String printName(String name) {return name;}private Integer printAge(Integer age) {return age;}public static void printOther() {System.out.println("Person.printOther");}
}
@Getter
@Setter
public class Demo {@Delegateprivate Person person;
}

编译后生成:

public class Demo {private Person person;public Demo() {}public Person getPerson() {return this.person;}public void setPerson(Person person) {this.person = person;}public void personMsg() {this.getPerson().personMsg();}public String printName(String name) {return this.getPerson().printName(name);}
}


使用:

public class Main {public static void main(String[] args) {Demo demo = new Demo();demo.setPerson(new Person());demo.personMsg();System.out.println(demo.printName("lucky"));}
}

@Singular

使用 @Singular 注解一个集合字段(如果没有指定 value 属性值,那么集合字段名需要是复数形式),会生成添加元素方法向集合添加单个元素

只能配合@Builder注解使用, 该注解作用于字段和参数上, 一般用在集合属性和集合参数


使用:

public class Main {public static void main(String[] args) {Demo demo = Demo.builder().name("lucky").num(1).num(2).num(3).build();System.out.println("demo = " + demo);}
}控制台输出:
demo = Demo(name=lucky, nums=[1, 2, 3])

lombok: 优秀blog

Lombok工具 : 常用注解介绍 (全)相关推荐

  1. Linux下查看某个进程打开的文件数-losf工具常用参数介绍

    Linux下查看某个进程打开的文件数-losf工具常用参数介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在linux操作系统中,一切皆文件.通过文件不仅仅可以访问常规数据,还 ...

  2. SpringBoot | 第六章:常用注解介绍及简单使用

    前言 之前几个章节,大部分都是算介绍springboot的一些外围配置,比如日志 配置等.这章节开始,开始总结一些关于springboot的综合开发的知识点.由于SpringBoot本身是基于Spri ...

  3. sg-uap mysql_SG-UAP常用注解介绍

    注解基本介绍 Annotation(注解)是JDK5.0及以后版本引入的.它可以用于创建文档,跟踪代码中的依赖性,甚至执行基本编译时检查.注解是以'@注解名'在代码中存在的,根据注解参数的个数,我们可 ...

  4. SpringMVC之Controller常用注解功能全解析

    一.简介 在SpringMVC中,控制器Controller负责处理由DispatcherServlet分发的请求,它把用户请求的数据经过业务处理层处理之后封装成一个Model ,然后再把该Model ...

  5. 【chip-tool】chip-tool工具常用指令介绍

    chip-tool 工具可用于调试 matter 设备,是matter协议新兴起时所使用的重要工具,由于资料都是英文 的很不友好,因此本文根据官方教程和自己的理解整理如下,本文主要介绍 chip-to ...

  6. lombok常用注解大全

    lombok可以帮助我们提升日常开发的效率jar包.里面有许多实用的注解. 本文将对lombok的常用注解作使用介绍,对于一些实验性官方不推荐的注解只会简单介绍 实验性注解可能会带来一些风险. 注: ...

  7. springboot依赖lombok插件、lombok常用注解

    --springboot依赖lombok插件.lombok常用注解 1 lombok插件 1.1 lombok插件简介 官方介绍如下: 意思是:lombok是一个能自动插入到编辑器和构建工具的java ...

  8. HuTool工具的使用介绍和常用案例

    HuTool工具的使用介绍和常用案例 一. 是什么 ​ 一个小而全的java工具类,静态方法封装.由开源项目作者的项目中一个util包衍变而来,里面包含了各种平时我们会用到的工具类. ​ 官方文档 二 ...

  9. ANDROID 开发常用的框架、工具、API最全集合

    以下是我整理的安卓开发常用的工具.框架.API的集合,希望大家有帮助! 1.RecyclerView items的动画库 github https://github.com/wasabeef/recy ...

最新文章

  1. 卧槽,又来一个 Java 神器!!
  2. C语言中的extern关键字用法
  3. Spring错误小结
  4. Kalman Filter
  5. eclipse 中 Android sdk 无法更新的问题
  6. TensorFlow基础篇(五)——tf.constant()
  7. Docker第三方项目小结
  8. Windows Server 2003 SP2 中文版下载
  9. cad完全卸载教程_怎么把CAD卸载干净,老司机来教你
  10. java 传入一个日期, 计算公历节日和农历节假日的常用类(包括除夕、清明节、母亲节、父亲节的算法)
  11. 服务器开启虚拟化有什么好处
  12. 计算机网络各层网络设备(中继器、集线器、网桥、交换机、路由器、网关)总结
  13. 常用计算机防治病毒软件有哪些,如何防治计算机病毒?常用的反病毒软件有哪些?...
  14. elasticsearch7.8.0入门操作
  15. bind智能DNS + bindUI管理系统(postgresql + bind dlz)
  16. 【Unity入门】软件Unity Hub和Unity的安装和简单尝试
  17. Docker学习(四):Dockerfile
  18. 计算机考试C1-1随笔
  19. H3C交换机SSH登录配置
  20. 对于环形组网次优和来回路径不一致的解决方法

热门文章

  1. 旅行社微信小程序,助力旅游企业引流获客,提高转化率
  2. Windows10系统能上微信QQ但不能上任何浏览器的解决方案之一
  3. 史上最全,Spring Boot入门篇总结,收藏起来慢慢看
  4. 深入理解public static ltTgt T max(Collectionlt? extends Tgt coll,Comparator lt? super Tgt comp)
  5. manjaro 安装dracut
  6. QPM 之悬浮窗助力性能优化
  7. PostgreSQL 修改默认用户 postgres 的密码 - 图形化界面操作
  8. IDEA_02 修改项目编码格式修改字体,大小
  9. 对熊猫太过痴迷,日本人连手游都不放过......
  10. 力扣让我心碎的第六天