日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學(xué)無先后,達(dá)者為師

網(wǎng)站首頁 編程語言 正文

@NoArgsConstructor、@AllArgsConstructor、@RequiredArgsConstructor的區(qū)別以及在springboot常用地方

作者:搏·夢 更新時間: 2022-05-25 編程語言

文章目錄

  • 1. 先說結(jié)論
  • 2. 代碼解析區(qū)別
    • 1. @AllArgsConstructor
    • 2. @RequiredArgsConstructor
  • 3. 場景使用---代替@Autowired注入bean對象
    • 1. @AllArgsConstructor
    • 2. @RequiredArgsConstructor
    • 3. @RequiredArgsConstructor 與 @AllArgsConstructor 在注入bean上的區(qū)別
  • 4. 總結(jié)

1. 先說結(jié)論

  1. 區(qū)別:
    @NoArgsConstructor:生成無參的構(gòu)造方法。
    @AllArgsConstructor:生成該類下全部屬性的構(gòu)造方法。
    @RequiredArgsConstructor:生成該類下被final修飾或者non-null字段生成一個構(gòu)造方法。
  2. 場景:
    在springboot中,對于一個bean類,注入其他bean的時候,常見的是使用@Autowired,實際上也可以使用構(gòu)造函數(shù)注入,這個時候就可以使用@AllArgsConstructor或者@RequiredArgsConstructor來代替

2. 代碼解析區(qū)別

  1. @NoArgsConstructor 默認(rèn)都知道。
  2. 若不知道怎么查看java反編譯字節(jié)碼內(nèi)容,可以看一下:
    Java 如何進行反編譯生成.java文件(javap、jad下載安裝使用)

1. @AllArgsConstructor

@AllArgsConstructor
public class demo {

    private String name;

    // 被final修飾
    private final String age;

    @NonNull
    private String sex;
}

根據(jù)反編譯查看代碼:

public class demo
{
	// 默認(rèn) 只要是該類下的字段,無論什么修飾,都會被參與構(gòu)造
    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
{
	// 只構(gòu)造了有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

根據(jù)上面看反編譯代碼可以得出:只要是類里面字段,都會被加入到構(gòu)造函數(shù)里面,不管被什么修飾。
例子:

@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:只會構(gòu)造被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修飾。注:強調(diào) 對需要的字段,為什么要強調(diào),請看下面的例子:

3. @RequiredArgsConstructor 與 @AllArgsConstructor 在注入bean上的區(qū)別

  1. 根據(jù)上面兩個例子,我們可以看出無論是那種方法都可以注入bean屬性對象,只是@RequiredArgsConstructor 是針對有條件的,沒有什么區(qū)別。

  2. 但如果是下面的需求呢:
    在該類下,部分字段還需要使用@Value來注入值呢?

    @Component
    @ToString
    public class ConstructorDemo {
    
        private BeanTest1 beanTest1;
    
        @NonNull
        private BeanTest2 beanTest2;
    
        private BeanTest3 beanTest3;
    
        @Value("${constructor.name:hello}")
        private String name;
        
    }
    
    先思考一下:
    一個bean如果使用構(gòu)造函數(shù)進行bean屬性注入,那么當(dāng)然構(gòu)造函數(shù)不能加上name。
    因為加上,在創(chuàng)建ConstructorDemo該bean的時候,需要找類型為String,名字是name的bean對象,當(dāng)然是不存在,必然會報錯。
    因此,當(dāng)然不能使用@AllArgsConstructor了,只能使用@RequiredArgsConstructor
    
  3. @AllArgsConstructor例子:

    @Component
    @ToString
    @AllArgsConstructor
    public class ConstructorDemo {
    
        private BeanTest1 beanTest1;
    
        @NonNull
        private BeanTest2 beanTest2;
    
        private BeanTest3 beanTest3;
    
        @Value("${constructor.name:hello}")
        private String name;
    }
    

    在這里插入圖片描述

  4. @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. 總結(jié)

  1. 上面只是舉例了代替@Autowired的例子,實際上在json轉(zhuǎn)化為對象,以及在spring中從配置文件讀取配置使用@ConfigurationProperties以及@ConstructorBinding的時候,都可以使用構(gòu)造函數(shù)賦值,都可以用到上面的兩個@AllArgsConstructor、@RequiredArgsConstructor。
  2. 具體:只要記得,那些字段需要賦值,就把它列進構(gòu)造方法的參數(shù)里面即可。

原文鏈接:https://blog.csdn.net/xueyijin/article/details/124618309

欄目分類
最近更新