SpringBoot系列之注解@Autowired VS @Qualifier VS @Primary(五)


前言

我們看到這幾篇內容都是掌握基礎,避免后續我們做項目時回頭重新復習,所以本節我們來討論下注解@Autowired和@Qualifier的區別所在。

@Autowired VS @Qualifier VS @Primary

首先我們定義如下一個車輛接口,我們知道車輛可以啟動和停止,所以在此接口中我們定義這兩個方法,如下:

package com.demo.springboot;

public interface Vehicle {
    String start();
    String stop();
}

接下來我們定義汽車和自行車類來實現上述接口,如下:

package com.demo.springboot;

import org.springframework.stereotype.Component;

@Component
public class Bike implements Vehicle {
    @Override
    public String start() {
        return "Bike started";
    }

    @Override
    public String stop() {
        return "Bike stopped";
    }
}
package com.demo.springboot;

import org.springframework.stereotype.Component;

@Component
public class Car implements Vehicle {
    @Override
    public String start() {
        return  "Car started";
    }

    @Override
    public String stop() {
        return "Car stopped";
    }
}

接下來我們定義車輛服務類,並調用車輛接口,如下:

package com.demo.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class VehicleService {
    
    @Autowired
    private Vehicle vehicle;

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}

我們在通過汽車和自行車實現車輛接口,同時通過添加注解@Component來創建bean,接下來我們在創建車輛服務類時通過注解@Autowired來獲取Spring IOC容器中的車輛bean,但是此時我們發現車輛接口是不明確的,我們不知道此接口的具體實現到底是汽車還是自行車,所以編譯器自動報錯如下:

這個時候注解@Qualifier就派上用場了,通過此單詞解釋也了然,意為限定:如果有多個相同類型的bean,則@Qualifier批注用於解決自動注解@Autowired沖突。 所以我們需要通過注解@Qualifier來明確限定該接口的實例時汽車還是自行車類,這里我們限定為自行車類,如下:

package com.demo.springboot;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class VehicleService {

    @Autowired
    @Qualifier("bike")
    private Vehicle vehicle;

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}

注解@Autowired既可以作用於字段,也可以作用於構造函數,使用注解@Autowired作用於構造函數時,在Spring 4.3版本后(如果我沒記錯的話)可以省略注解@Autowired,所以我們如上可以等同如下:

package com.demo.springboot;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class VehicleService {
    
    private Vehicle vehicle;

    public VehicleService(@Qualifier("bike") Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}

如上是我們在使用接口具體實例時使用注解@Qualifier限定,要是針對車輛接口的具體實現汽車和自行車類,我們有一個總是想注入的實現,也就是說在接口具體實現源頭就指定而非調用時指定,此時我們應該怎么辦呢?此時我們可以使用注解@Primary,如下:

package com.demo.springboot;

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

@Component
@Primary
public class Bike implements Vehicle {
    @Override
    public String start() {
        return "Bike started";
    }

    @Override
    public String stop() {
        return "Bike stopped";
    }
}
package com.demo.springboot;

import org.springframework.stereotype.Service;

@Service
public class VehicleService {

    private Vehicle vehicle;

    public VehicleService(Vehicle vehicle) {
        this.vehicle = vehicle;
    }

    public String start() {
        return vehicle.start();
    }

    public String stop() {
        return vehicle.stop();
    }
}

想必通過如上簡單的例子我們明白了如題三者的使用,我們同樣來下一個結論:@Autowired注解使我們能夠將依賴項注入bean,當可以按類型能夠唯一地找到每個bean時,它無需附加配置就可以很好地工作,但是當我們可以注入多個bean時,我們必須使用注解@Qualifier按名稱或注解@Primary指定主體來幫助Spring找到所需的具體實現。 

總結

本節簡短的內容我們到此結束,關於一些基本注解的使用和區別到這里就已結束,后續遇到其他的繼續通過博文補充,下一節我們將進入Web的旅行,感謝您的閱讀,我們下節見。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM