初始化准备工作
所有的环境如下:
- jdk1.8或者jdk11
- Springboot2.x
- mysql5.7或者mysql8.0
首先创建Springboot工程,初次创建初始化速度慢
如果想指定单个项目的maven中央仓库,pom中的配置如下:
<!-- 代码库 -->
<repositories>
<repository>
<id>maven-ali</id>
<url>http://maven.aliyun.com/nexus/content/groups/public//</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
<checksumPolicy>fail</checksumPolicy>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
Lombok
Lombok简介
java工程中,我们要创建很多的java Bean。这些javaBean中都会写getter,setter,equals,hashCode和toString的模板代码,这些代码都没啥技术含量。
那么我们就是使用Lombok来自动生成这些代码,通过注解的方式。提高我们的工作效率。
Lombok的原理:JSR 269插件化注解处理。就是在编译生成字节码之前,Lombok根据自己编写的注解处理器,动态地修改 AST增加新的节点(即Lombok自定义注解所需要生成的代码),最终生成JVM可执行的字节码Class文件。
什么是JSR 269?
JSR 269: Pluggable Annotation Processing API
实现在Javac编译阶段利用“Annotation Processor”对自定义的注解进行预处理后生成真正在JVM上面执行的“Class文件
- java反射技术的对比
- 使用Annotation Processing自定义注解是在编译阶段进行修改
- JDK的反射技术是在运行时动态修改
结论:反射更加灵活一些但是带来的性能损耗更加大
安装
- 安装插件。在idea工具中安装Lombok插件,安装完成后重启idea
- 添加依赖
<!--scope=provided,说明它只在编译阶段生效,不需要打入包中, Lombok在编译期将带Lombok注解的Java文件正确编译为完整的Class文件-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
<scope>provided</scope>
</dependency>
开启 annotation processing,重启idea
@getter和@setter注解
- 作用
- 生成对应的getter和setter方法
- 使用方法
- 写在对应的属性上,生成此属性的getter和setter
- 写在类上,生成所有属性的getter和setter
- 方法控制访问级别 set和get注解加上 @Getter(AccessLevel.PROTECTED)
- 不想生成set、get方法@Getter(AccessLevel.NONE)
- 常量(final)只生成getter
- 静态变量不生成getter和setter
- 代码如下
具体效果可以先compile,然后在idea中查看对应的字节码文件。
import lombok.AccessLevel;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@Getter
@Setter
public class User {
// 生成私有的getter
@Getter(AccessLevel.PRIVATE)
private int id;
// 不生成setter
@Setter(AccessLevel.NONE)
private String username;
private String pwd;
private String phone;
private String email;
private Date createTime;
// final 没有setter
private final String status = "启动";
// static 没有getter和setter
private static String address = "河南洛阳";
}
@NonNull注解
- 作用:作用于方法上或者属性,用于非空判断,如果为空则抛异常
- 代码
@NonNull
private String pwd;
public void login(@NonNull String pwd){
System.out.println("登录");
}
构造方法相关注解
- @NoArgsConstructor
- 生成无参构造器
- @AllArgsConstructor
- 生成全参构造器
- final和static属性不生成
- @RequiredArgsConstructor
- 指定参数的构造函数,有以下的特征的字段
- final类型未被初始化的属性, 标记了@NonNull的属性
- 标记了@NonNull的属性
- 注意:自定义的构造函数不要冲突,主要是类型
- 理解此注解,需要结合final关键字的含义
- @NoArgsConstructor不能加
- 指定参数的构造函数,有以下的特征的字段
@ToString注解
- 作用:重写toString方法,方便调试。
- 使用:写在类名上
- 默认输出所有属性
- 不包含某个属性
- 只输入指定属性
//不包含某个属性
@ToString(exclude = {"age"})
//只输入指定属性
@ToString(of = {"name"})
@EqualsAndHashCode注解
作用:@EqualsAndHashCode注解可以重写对象的HashCode方法和equals方法
我们先来了解下这两个方法:
- HashCode⽅法
- 顶级类Object⾥⾯的⽅法,所有类都是继承Object的,返回值int类型
- 根据⼀定的hash规则(存储地址,字段,或者⻓度等),映射成⼀个数值,即散列值
- Equals⽅法
- 顶级类Object⾥⾯的⽅法,所有类都是继承Object的,返回值boolean类型
- 根据⾃定义的匹配规则,⽤于匹配两个对象是否⼀样, ⼀般逻辑是如下
//判断地址是否⼀样
//⾮空判断和class类型判断
//强转
//对象⾥⾯的字段⼀⼀匹配
那为什么要对比这么多内容?
如果两个对象相等,那么它们的hashCode()值一定相同(这里的相等是指,通过equals()比较两个对象时返回true)
如果两个对象hashCode()相等,它们并不一定相等。在散列表中hashCode()相等,即两个键值对的哈希值相等。
然而哈希值相等,并不一定能得出键值对相等,就出现所谓的哈希冲突场景,还需判断equals⽅法判断对象是否相
应用场景:
当向集合中插⼊对象时,如何判别在集合中是否已经存在该对象,⽐如Set确保存储对象的 唯⼀,并判断是不是同个对象呢?
依据hashCode和equals进⾏判断
所以Set存储的对象必须重写这两个⽅法 判断两个对象是否⼀样
⾸先判断插⼊obj的hashcode值是否存在,hashcode值不存在则直 接插⼊集合
值存在则还需判断equals⽅法判断对象是否相等
接下来看一段代码:
Set<User> set = new HashSet<>();
User u1 = new User("123456");
User u2 = new User("123456");
System.out.println(u1==u2); // 返回false,在内存中的地址是不一样的
set.add(u1);
set.add(u2);
System.out.println(set.size()); // 长度为2,表示两个都添加成功
然后在User中添加@EqualsAndHashCode注解,还是运行上面的代码,发现长度为1。
使用:
- 作用于类,覆盖默认的equals和hashCode, 作用于全部属性
- 不包括某个属性
@EqualsAndHashCode(exclude = {"age"})
- 只输出某个属性
@EqualsAndHashCode(of = {"name"})
@Data注解
Lombok前面讲了多个注解,一个个加也麻烦
- @Data, 定义一个干净的类,增加此注解,mvn compile查看字节码
- 作用于类上,是以下注解的集合
- @ToString
- @EqualsAndHashCode
- @Getter
- @Setter
- @RequiredArgsConstructor
@Builder注解
构造者模式:又称之为建造者模式
- 场景:当一个bean类重载了多个构造方法时,并且参数随机使用时,考虑使用构造者模式
- 代码
@Data
@Builder
public class Student {
private int id;
private String username;
private String pwd="";
private final String phone="";
private String email;
private Date createTime;
// final 没有setter
private final String status = "启动";
// static 没有getter和setter
private static String address = "河南洛阳";
}
Student student = Student.builder().id(123).pwd("1").username("张三").build();
@Log和@Slf4j注解
- @Log / @Slf4j
- 作用于类上,生成日志变量, 用于记录日志
- 如果不生效,记得检查下面的配置,另外重新更新下lombok插件,重启idea
- 开始按照创建的那边,记得开启 开启annotion processing
- 使用
@Slf4j
public class StudentDO {
public void test(String email){
log.info("test方法测试");
this.email = email;
}
}
//字节码
public class StudentDO {
private static final Logger log = Logger.getLogger(StudentDO.class.getName());
}