[英]How to inject resource Class instance in Spring using Dependency injection
[英]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.