簡體   English   中英

如何在抽象 class 中使用構造函數注入注入特定依賴項?

[英]How to inject specific dependency using constructor injection in an abstract class?

我有一個abstract的 class ,它具有以下構造函數-

abstract class AbstractA<T> {
    protected CrudRepository<T, Long> crudRepository;  
    AbstractA(CrudRepository crudRepository) {
        this.crudRepository = crudRepository;
    }
}

abstract class AbstractB extend AbstractA<TableB> {
    protected Service service;
    // I want to autowire ConcreteCrudReposity here, but get myService from  
    //  subclass which is not a spring service.
    @Autowired 
    AbstractB(
        ConcreteCrudRepository<TableB, Long> concreteCrudRepository,
        MyService myService) {
        super(concreteCrudRepository);
    } 
}
class  AB extend AbstractB {
    AB() {
        super(new MyService()); // I know this is lame
    }
}

我想使用構造函數注入在抽象 class AbstractB 中注入 spring 服務,但其他服務(MyService)需要來自不是 Z2A2D595E6ED9A0B24F027F2B63B134DZ 服務的子類。

我知道我可以@Autowire子 class 中的依賴項,但是可以在AbstractB中執行此操作,因為此依賴項實際上應該從AbstractB注入(請參閱通用實體類型)。 而且我只有構造函數注入作為選項。 請注意,我使用的是 generics 並且我沒有顯示更多代碼以保持問題簡單。

您可以自動連接到具體的 class,並使用 arguments 調用超級構造函數

    @Component
    class  AB extend AbstractB {
    @Autowired 
         AB(ConcreteCrudRepository concreteCrudRepository) {
            super(concreteCrudRepository, new MyService()); // I know this is lame
        }
    }

一個小技巧是在超級class中使用場注入

abstract class AbstractA {
    @Autowired
    protected CrudRepository crudRepository; 
}

或者setter-injection ,它更干凈,更容易測試:

abstract class AbstractA {
    protected CrudRepository crudRepository;

    @Autowired
    protected void setCrudRepository(CrudRepository crudRepository) {
        this.crudRepository = crudRepository;
    }
}

據我所知,這可以應用於層次結構中盡可能多的類。

正如編譯器所說,在 java 中,您必須提供一個構造函數“匹配超級”。 不用管 spring,如果你不在 java 中這樣做 - 它甚至不會編譯。

因此,假設您在問題中定義了帶有構造函數的抽象類,您別無選擇,只能像這樣定義具體的 class :

 @Component
    class  AB extend AbstractB {
         @Autowired // putting autowired is not mandatory, btw as long as you have a single constructor in descent spring versions
         AB(ConcreteCrudRepository concreteCrudRepository, Service service) {
            super(concreteCrudRepository, service);
        }
    }

Allocating the Service with new in the constructor will work from java standpoint (will compile and run), but you've said by yourself that it should be managed by spring, and obviously when you use new like this, spring will know nothing about this服務,例如,如果MyService自己有依賴項,它們將不會被注入。

讓我也參考您的評論:

問題是 ConcreteCrudRepository 確實屬於 AbstractB

您基本上使用的是具體的 class AB而不是抽象的 class - 在 Java 中,您無法在全部實例化 ZA2ZF22ED4F8EBC2C12 的抽象 ZA2ZF22ED4F8EBC2CBB1。 AB維護 state:服務和存儲庫。 確實,從技術上講,它是以“借用”超類代碼的方式編寫的,但我建議您認為您使用的是“獨立”class。

最后一點是關於諸如AB之類的眾多類:

只要 spring 管理它們(像AB ,服務和存儲庫這樣的子類),這應該不是問題:

Spring 應該“足夠聰明”來解決這樣的依賴關系並注入任何需要的東西,只要它再次管理所有這些子類:注入的“魔力”只能發生在由 spring 本身管理的類中。

確實,如果您需要在 spring 中添加關於應該注入什么的“提示”,您可以使用@Qualifier之類的技術,但它已經是另一回事了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM