解读@NoArgsConstructor,@AllArgsConstructor,@RequiredArgsConstructor的区别及在springboot常用地方

 更新时间:2023年12月15日 14:25:45   作者:搏·梦  
这篇文章主要介绍了解读@NoArgsConstructor,@AllArgsConstructor,@RequiredArgsConstructor的区别及在springboot常用地方,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1. 先说结论

区别

  • @NoArgsConstructor:生成无参的构造方法。
  • @AllArgsConstructor:生成该类下全部属性的构造方法。
  • @RequiredArgsConstructor:生成该类下被final修饰或者non-null字段生成一个构造方法。

场景

在springboot中,对于一个bean类,注入其他bean的时候,常见的是使用@Autowired,实际上也可以使用构造函数注入,这个时候就可以使用@AllArgsConstructor或者@RequiredArgsConstructor来代替

2. 代码解析区别

@NoArgsConstructor 默认都知道。

若不知道怎么查看java反编译字节码内容,可以看一下:

Java如何进行反编译生成.java文件(javap、jad下载安装使用)

1. @AllArgsConstructor

@AllArgsConstructor
public class demo {

    private String name;

    // 被final修饰
    private final String age;

    @NonNull
    private String sex;
}

根据反编译查看代码:

public class demo
{
	// 默认 只要是该类下的字段,无论什么修饰,都会被参与构造
    public demo(String name, String age, String sex)
    {
        if(sex == null)
        {
            throw new NullPointerException("sex is marked non-null but is null");
        } else
        {
            this.name = name;
            this.age = age;
            this.sex = sex;
            return;
        }
    }

    private String name;
    private final String age;
    private String sex;
}

2. @RequiredArgsConstructor

@RequiredArgsConstructor
public class demo {

    private String name;

    // 被final修饰
    private final String age;

    @NonNull
    private String sex;
}

反编译代码:

public class demo
{
	// 只构造了有final或者no-null修饰的字段
    public demo(String age, String sex)
    {
        if(sex == null)
        {
            throw new NullPointerException("sex is marked non-null but is null");
        } else
        {
            this.age = age;
            this.sex = sex;
            return;
        }
    }

    private String name;
    private final String age;
    private String sex;
}

这是源码的英文解释:

3. 场景使用—代替@Autowired注入bean对象

1. @AllArgsConstructor

根据上面看反编译代码可以得出:只要是类里面字段,都会被加入到构造函数里面,不管被什么修饰。

例子:

@Component
public class BeanTest1 {
}

@Component
public class BeanTest2 {
}

@Component
public class BeanTest3 {
}

@Component
@AllArgsConstructor
@ToString
public class ConstructorDemo {
	// 注入三个bean对象,完全没有使用Autowired注解
    private BeanTest1 beanTest1;

    @NonNull
    private BeanTest2 beanTest2;

    private final BeanTest3 beanTest3;
}

// 这只是个测试类
@Component
public class ConstructorRunner implements ApplicationRunner {

    @Autowired
   ConstructorDemo ConstructorDemo;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println(ConstructorDemo);
    }
}

完完全全可以注入bean对象。

2. @RequiredArgsConstructor

RequiredArgsConstructor:只会构造被final修饰或者no-null修饰的字段。

// 改成@RequiredArgsConstructor
@Component
@RequiredArgsConstructor
@ToString
public class ConstructorDemo {

    private BeanTest1 beanTest1;

    @NonNull
    private BeanTest2 beanTest2;

    private final BeanTest3 beanTest3;
}

由图可以看出,没有被修饰final或者no-null的属性无法被注入,因此,建议使用@RequiredArgsConstructor的时候,对需要的字段加上final修饰

注:强调 对需要的字段,为什么要强调,请看下面的例子:

3. @RequiredArgsConstructor与@AllArgsConstructor在注入bean上区别

根据上面两个例子,我们可以看出无论是那种方法都可以注入bean属性对象,只是@RequiredArgsConstructor 是针对有条件的,没有什么区别。

但如果是下面的需求呢:

在该类下,部分字段还需要使用@Value来注入值呢?

@Component
@ToString
public class ConstructorDemo {

    private BeanTest1 beanTest1;

    @NonNull
    private BeanTest2 beanTest2;

    private BeanTest3 beanTest3;

    @Value("${constructor.name:hello}")
    private String name;
    
}

先思考一下:

一个bean如果使用构造函数进行bean属性注入,那么当然构造函数不能加上name。

因为加上,在创建ConstructorDemo该bean的时候,需要找类型为String,名字是name的bean对象,当然是不存在,必然会报错。

因此,当然不能使用@AllArgsConstructor了,只能使用@RequiredArgsConstructor

@AllArgsConstructor例子:

@Component
@ToString
@AllArgsConstructor
public class ConstructorDemo {

    private BeanTest1 beanTest1;

    @NonNull
    private BeanTest2 beanTest2;

    private BeanTest3 beanTest3;

    @Value("${constructor.name:hello}")
    private String name;
}

@RequiredArgsConstructor的例子

@Component
@ToString
@RequiredArgsConstructor
public class ConstructorDemo {
	// 肯定为null,因为没有final或者no-null修饰
    private BeanTest1 beanTest1;

    @NonNull
    private BeanTest2 beanTest2;

    private final BeanTest3 beanTest3;

    @Value("${constructor.name:hello}")
    private String name;
}

4. 总结

上面只是举例了代替@Autowired的例子,实际上在json转化为对象,以及在spring中从配置文件读取配置使用@ConfigurationProperties以及@ConstructorBinding的时候都可以使用构造函数赋值,都可以用到上面的两个@AllArgsConstructor、@RequiredArgsConstructor。

具体:只要记得,那些字段需要赋值,就把它列进构造方法的参数里面即可。

好了,以上仅为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • java语言基础之标识符和命名规则详解

    java语言基础之标识符和命名规则详解

    这篇文章主要给大家介绍了关于java语言基础之标识符和命名规则的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03
  • SpringBoot事务注解超详细讲解

    SpringBoot事务注解超详细讲解

    这篇文章主要给大家介绍了关于SpringBoot事务注解的相关资料,在Spring Boot中,事务管理是一个非常重要的概念,我们可以使用事务注解来控制事务的行为,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2023-11-11
  • Netty分布式ByteBuf使用命中缓存的分配解析

    Netty分布式ByteBuf使用命中缓存的分配解析

    这篇文章主要为大家介绍了Netty分布式ByteBuf 使用命中缓存的分配解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-03-03
  • 基于Java实现Json文件转换为Excel文件

    基于Java实现Json文件转换为Excel文件

    这篇文章主要为大家详细介绍了如何利用Java实现Json文件转换为Excel文件,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下
    2022-12-12
  • java char数据类型原理解析

    java char数据类型原理解析

    这篇文章主要介绍了java char数据类型原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • 使用Springboot 打jar包实现分离依赖lib和配置

    使用Springboot 打jar包实现分离依赖lib和配置

    这篇文章主要介绍了使用Springboot 打jar包实现分离依赖lib和配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-02-02
  • Java面试题冲刺第二十六天--实战编程

    Java面试题冲刺第二十六天--实战编程

    这篇文章主要为大家分享了最有价值的三道java实战面试题,涵盖内容全面,包括数据结构和算法相关的题目、经典面试编程题等,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • java的反射用不好试试内省?

    java的反射用不好试试内省?

    使用内省相对于直接使用反射更加安全可靠,Java的反射机制比较特殊,它不同于一般的编程方式,稍不小心就容易破坏类的封装性。练的不好,就容易走火入魔。没关系,很多时候我们还可以使用Java的内省机制哦
    2021-07-07
  • Java线程的联合用法实例分析

    Java线程的联合用法实例分析

    这篇文章主要介绍了Java线程的联合用法,结合实例形式分析了java线程联合的原理、实现方法及相关操作技巧,需要的朋友可以参考下
    2019-10-10
  • 详解SpringBoot集成消息队列的案例应用

    详解SpringBoot集成消息队列的案例应用

    Message Queue又名消息队列,是一种异步通讯的中间件。可以理解为邮局,发送者将消息投递到邮局,然后邮局帮我们发送给具体的接收者,具体发送过程和时间与我们无关。 消息队列是分布式系统中重要的组件,消息队列主要解决了应用耦合、异步处理、流量削锋等问题
    2022-04-04

最新评论