最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring使用注解進行對象裝配(DI)的操作

 更新時間:2023年07月28日 11:18:02   作者:韻秋梧桐  
獲取Bean對象也叫做對象裝配,就是把對象取出來放到某個類中,有時候也叫對象注入,這篇文章主要介紹了Spring使用注解進行對象裝配(DI),需要的朋友可以參考下

一. 什么是對象裝配

獲取 Bean 對象也叫做對象裝配,就是把對象取出來放到某個類中,有時候也叫對象注入。對象裝配(對象注入)的實現(xiàn)方法以下 3 種:

  • 屬性注入 ,就是將對象注入到某個類的一個屬性當中。
  • 構(gòu)造方法注入 ,就是通過構(gòu)造方法來將對象注入到類中。
  • Setter 注入 ,通過 SetXXX 系列方法將對象注入到類中。

常見有關(guān)對象注入的注解有兩個,一個是@Autowired,另外一個是@Resource

??它們兩者的區(qū)別如下:

  • 出身不同:@Autowired 是由Spring提供的,而 @Resource 是JDK提供的。
  • 查找順序不同:從容器中獲取對象時 @Autowired 先根據(jù)類型再根據(jù)名稱查詢,而 @Resource 先根據(jù)名稱再根據(jù)類型查詢。
  • 使?時設(shè)置的參數(shù)不同:@Resource 支持更多的參數(shù)設(shè)置(有 7 個),如name、type等,而@Autowired只支持設(shè)置required一個參數(shù),用來設(shè)置注入 Bean 的時候該 Bean 是否必須存在(true/false)。

img

img

  • 依賴注入支持不同:@Autowired 支持屬性注入,構(gòu)造方法注入和 Setter 注入,而 @Resource 只支持屬性注入和 Settter 注入,但是不支持構(gòu)造方法注入。
  • 對 IDEA 的兼容性支持不同:使用 @Autowired 在 IDEA 旗艦版下可能會有誤報(設(shè)置required即可);而 @Resource 不存在誤報的問題。

二. 三種注入方式

1. 屬性注入

屬性注入只需要在需要注入對象的屬性上加上 @Autowired 或者 @Resource 注解就可以了,這里以 @Autowired 為例。

首先來看第一種情況,待注入的同類對象只有一個,此時我們直接使用 @Autowired 注解就好,不必設(shè)置參數(shù),例如我們在UserController類里面注入UserService對象。

下面UserService的結(jié)構(gòu),先使用 @Service 將 Bean 存放到 Spring 中:

屬性注入:

package com.tr.demo.controller;
import com.tr.demo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
    //屬性注入
    @Autowired
    private UserService userService;
    public void sayHi() {
        userService.sayHi();
    }
}

此時我們就可以在啟動類中,使用上下文對象來獲取到UserController對象,通過執(zhí)行UserController對象的sayHi方法來進而調(diào)用到注入的UserService對象中的sayHi方法了,此時的UserService對象就不是我們自己new出來的了。

import com.tr.demo.controller.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController usercontroller =  context.getBean("userController", UserController.class);
        usercontroller.sayHi();
    }
}

運行結(jié)果:

img

上面說的是同類對象只有一個的情況,而如果存在多個同類對象,我們就得通過參數(shù)來告知容器我們要注入哪一個對象,不告知就會報錯。

比如我們將多個User對象添加到容器中,如下:

package com.tr.demo.model;
// User 結(jié)構(gòu)
public class User {
    private int id;
    private String name;
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
package com.tr.demo.model;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
@Component
public class UserBeans {
    // 使用方法注解添加多個 User 對象到容器中
    @Bean("user1")
    public User user1(){
        User user = new User();
        user.setId(1);
        user.setName("張三");
        return user;
    }
    @Bean("user2")
    public User user2(){
        User user = new User();
        user.setId(2);
        user.setName("李四");
        return user;
    }
    @Bean("user3")
    public User user3(){
        User user = new User();
        user.setId(3);
        user.setName("王五");
        return user;
    }
}

而在UserController2類中需要注入User對象,此時我們運行程序就會報錯:

package com.tr.demo.controller;
import com.tr.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController2 {
    @Autowired
    private User user;
    public void sayHi() {
        System.out.println("Hello, " + user);
    }
}

我們試著以同樣的方法來調(diào)用sayHi方法:

運行結(jié)果:

@Autowired 依賴注入流程首先是先根據(jù)類型從容器中獲取對象,如果只能獲取到一個,那么就直接將此對象注入到當前屬性上;如果能獲取到多個對象,此時會使用 BeanName 進行匹配,而我們添加到 Spring 中的對象是沒有一個叫user的,所以程序就報錯了。

img

此時就需要我們來告知容器我們需要哪一個具體的 Bean,要獲得目標對象主要有下面三種方法:

1??方法1:將屬性的變量名設(shè)置為你需要的那個BeanName就可以了,后面的構(gòu)造方法與 Setter 注入同理,將形參名設(shè)置成與BeanName相同即可。

img

img

2??方法2:@Autowired 注解與 @Qualifier 注解配合使用,設(shè)置 @Qualifier 的value參數(shù)為BeanName即可,要注意 @Qualifier 注解不能修飾方法,只能修飾變量。

img

img

3??方法3:將 @Autowired 注解替換成 @Resource 注解的,并將它name參數(shù)值設(shè)置為BeanName即可。

img

img

2. 構(gòu)造方法注入

在構(gòu)造方法加上 @Autowired 注解就可,要注意 @Resource 注解是不支持構(gòu)造方法注入的,我們就直接演示如何獲取取多個同類對象中的其中一個了,還是用上面添加到容器中的多個 User 對象。

方法1:將構(gòu)造方法形參名設(shè)置為user1

package com.tr.demo.controller;
import com.tr.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class UserController3 {
    private User user;
    @Autowired
    public UserController3(User user1) {
        this.user = user1;
    }
    public void sayHi() {
        System.out.println("Hello, " + user);
    }
}

啟動類就不貼代碼了,一樣的,運行結(jié)果如下:

img

方法2:@Autowired 搭配 @Qualifier

package com.tr.demo.controller;
import com.tr.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
@Controller
public class UserController4 {
    private User user;
    @Autowired
    public UserController4(@Qualifier(value = "user2") User user) {
        this.user = user;
    }
    public void sayHi() {
        System.out.println("Hello, " + user);
    }
}

運行結(jié)果:

img

對了,如果一個類中只有一個構(gòu)造方法,@Autowired 是可以省略的,演示一下:

package com.tr.demo.controller;
import com.tr.demo.model.User;
import org.springframework.stereotype.Controller;
@Controller
public class UserController5 {
    private User user;
    public UserController5(User user3) {
        this.user = user3;
    }
    public void sayHi() {
        System.out.println("Hello, " + user);
    }
}

此時仍然是可以成功注入對象。

img

如果有多個構(gòu)造方法,要注意此時是不能省略 @Autowired 的,會導致會注入對象失敗。

package com.tr.demo.controller;
import com.tr.demo.model.User;
import org.springframework.stereotype.Controller;
@Controller
public class UserController6 {
    private User user;
    public UserController6(User user1) {
        this.user = user1;
    }
    public UserController6() {
        System.out.println("調(diào)用無參構(gòu)造");
    }
    public void sayHi() {
        System.out.println("Hello, " + user);
    }
}

此時可以看到注入對象失敗了,輸出的結(jié)果是null。

img

當然此時加上 @Autowired 注解就能正常注入了,就不做展示了。

3. Setter注入

Setter 注入就是在 setXXX 系列方法上加上 @Resource 或者 @Autowired 進行注入,和構(gòu)造方法注入大同小異,簡單演示一下。

package com.tr.demo.controller;
import com.tr.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
@Controller
public class UserController7 {
    private User user;
    @Autowired
    public void setUser(@Qualifier(value = "user2") User user) {
        this.user = user;
    }
    public void sayHi() {
        System.out.println("Hello, " + user);
    }
}

啟動類和運行結(jié)果:

img

這里這里第一行輸入的是因為啟動程序會將上面寫的UserController6也添加到容器中,UserController6的無參構(gòu)造方法是我們自定義的。

三. 三種注入方式的優(yōu)缺點

在早期的 Spring 版本中,官方推薦使用的 Setter 注入,最開始說的原因就是不符合單一設(shè)計原則吧,而現(xiàn)在比較新的 Spring 版本(Sring 4.x 之后)中,官方最使用推薦的又是構(gòu)造方法注入了,說法是因為它的通用性最好。

??屬性注入

優(yōu)點:

  • 使用起來簡單方便

缺點:

  • 無法注入到一個final修飾的變量,因為 final 修飾的變量只有兩種賦值方式,一是直接賦值,二是通過構(gòu)造方法進行賦值,而屬性注入這兩種方式都不能滿足。

img

2.通用性問題,屬性注入只能在 IoC 容器中使用,在非 IoC 容器中是不可?的。

3.更容易違背單一設(shè)計原則,簡單理解就是注入方式越簡單,濫用的概率越大,就比如在數(shù)據(jù)持久層有一個針對用戶操作的類,本來這個類就只是注入用戶相關(guān)操作的依賴就行了,但由于屬性注入使用起來成本不高,程序猿就多注了一些依賴去完成了一些和用戶操作無關(guān)的內(nèi)容,這就違背了單一設(shè)計原則了。

??Setter 注入

優(yōu)點:

  • 通常情況下,setXXX 系列的方法中只會設(shè)置一個屬性,就更符合單一設(shè)計原則。

缺點:

  • 同樣的,也不能注入到一個 final 修飾的變量中。

img

  • 注入的對象是可能被修改的,因為 setXXX 系列的方法隨時都有可能被調(diào)用導致注入的 Bean 就被修改了。

??構(gòu)造方法注入

優(yōu)點:

可以注入到一個被 final 修飾的變量。

img

  • 注入對象不會被修改,因為構(gòu)造方法只會在對象創(chuàng)建時執(zhí)行一次,不存在注入對象被隨時修改的情況。
  • 可以保證注入對象的完全初始化,因為構(gòu)造方法是在對象創(chuàng)建之前執(zhí)行的。
  • 通用性最好,因為不管你怎么寫 Java 代碼,創(chuàng)建實例對象時都要執(zhí)行構(gòu)造方法吧。

缺點:

  • 相較于屬性注入,寫法更加復雜,如果有多個注?會顯得?較臃腫,但出現(xiàn)這種情況你應(yīng)該考慮?下當前類是否符合程序的單?職責的設(shè)計模式了。
  • 使用構(gòu)造注入,無法解決循環(huán)依賴的問題。

四. 綜合練習

在 Spring 項?中,通過 main ?法獲取到 Controller 類,調(diào)? Controller ??通過注?的?式調(diào)? Service 類,Service 再通過注?的?式獲取到 Repository 類,Repository 類??有?個?法構(gòu)建? 個 User 對象,返回給 main ?法。Repository ?需連接數(shù)據(jù)庫,使?偽代碼即可。

首先要清楚的是在 main 方法中是不能使用依賴注入的,因為類的靜態(tài)部分是在 Spring 注入之前的加載的,仔細想一下,在類加載時就要使用一個還沒注入的對象這是不現(xiàn)實的。

所以我們要在 main 中執(zhí)行的是將掃描路徑中的類添加到 Spring 中,對象的注入要在 mian 方法所在類的外部去實現(xiàn)。

img

運行結(jié)果:

img

到此這篇關(guān)于Spring使用注解進行對象裝配(DI)的文章就介紹到這了,更多相關(guān)spring對象裝配內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java8新特性-Stream入門學習心得

    java8新特性-Stream入門學習心得

    這篇文章主要介紹了java8新特性-Stream入門學習心得,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • Java常量池知識點總結(jié)

    Java常量池知識點總結(jié)

    本篇文章給大家通過理論原理等方便徹底分析了Java常量池的相關(guān)知識,有興趣的朋友閱讀學習下吧。
    2017-12-12
  • MyBatis Generator配置入門

    MyBatis Generator配置入門

    本文主要介紹了MyBatis Generator配置入門,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Java之while與do-while循環(huán)的用法詳解

    Java之while與do-while循環(huán)的用法詳解

    在上一篇文章中,給大家講解了循環(huán)的概念,并重點給大家講解了for循環(huán)的使用。但在Java中,除了for循環(huán)之外,還有while、do-while、foreach等循環(huán)形式。這篇文章給大家講解while循環(huán)的使用
    2023-05-05
  • java實現(xiàn)快速排序的方法

    java實現(xiàn)快速排序的方法

    這篇文章主要介紹了java實現(xiàn)快速排序的方法,涉及java排序的相關(guān)操作技巧,需要的朋友可以參考下
    2015-05-05
  • 帶你用Java方法輕松實現(xiàn)樹的同構(gòu)

    帶你用Java方法輕松實現(xiàn)樹的同構(gòu)

    給定兩棵樹T1和T2。如果T1可以通過若干次左右孩子互換就變成T2,則我們稱兩棵樹是“同構(gòu)”的。例如圖1給出的兩棵樹就是同構(gòu)的,因為我們把其中一棵樹的結(jié)點A、B、G的左右孩子互換后,就得到另外一棵樹
    2021-06-06
  • Java中防止XSS攻擊的10種方法

    Java中防止XSS攻擊的10種方法

    這篇文章主要給大家介紹了關(guān)于Java中防止XSS攻擊的10種方法,XSS(Cross Site Scripting)攻擊是一種常見的網(wǎng)絡(luò)安全漏洞,文中給出了詳細的代碼示例,需要的朋友可以參考下
    2023-07-07
  • 多數(shù)據(jù)源@DS和@Transactional實戰(zhàn)

    多數(shù)據(jù)源@DS和@Transactional實戰(zhàn)

    這篇文章主要介紹了多數(shù)據(jù)源@DS和@Transactional實戰(zhàn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • 詳解Spring極速集成注解redis實錄

    詳解Spring極速集成注解redis實錄

    這篇文章主要介紹了詳解Spring極速集成注解redis實錄,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • Java實現(xiàn)定時讀取json文件里內(nèi)容的示例代碼

    Java實現(xiàn)定時讀取json文件里內(nèi)容的示例代碼

    有時候我們會需要定時來讀取JSON配置文件里的內(nèi)容,來執(zhí)行一些業(yè)務(wù)邏輯上的操作,本文就介紹了Java實現(xiàn)定時讀取json文件里內(nèi)容的示例代碼,感興趣的可以了解一下
    2023-08-08

最新評論

上蔡县| 沛县| 饶河县| 左贡县| 通渭县| 罗城| 浏阳市| 湘乡市| 望江县| 南漳县| 龙门县| 安化县| 北流市| 太仆寺旗| 宜都市| 麻栗坡县| 温泉县| 襄樊市| 林甸县| 遵义市| 通州市| 泸西县| 淮安市| 秦皇岛市| 平乐县| 孙吴县| 灵石县| 平阴县| 云林县| 汉川市| 越西县| 辽阳县| 观塘区| 乌海市| 五寨县| 普陀区| 玉田县| 正定县| 三亚市| 高淳县| 泰和县|