[英]How to inject bean via generic variable in spring
我在用泛型類型注入bean時遇到問題。 看例子。 我將向服務注入類型從App類獲取的存儲庫。 現在我有例外:
沒有可用的類型為'asd.IRepository'的合格Bean:預期為單個匹配的Bean,但找到了2:a,b
asd是軟件包,僅供測試。
在這種情況下我該怎么辦? 有什么辦法嗎?
public interface IRepository<T, V> {
void print();
}
@Component
public class A implements IRepository<String,String> {
@Override
public void print() {
System.out.println("A");
}
}
@Component
public class B implements IRepository<Double,String> {
@Override
public void print() {
System.out.println("A");
}
}
@Service
public class ServiceABC<V, T> {
@Autowired
private IRepository<V,T> repo;
public void print(){
repo.print();
}
}
@Controller
public class App {
@Autowired
private ServiceABC<String, String> serviceABC;
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext("asd");
App app = ctx.getBean(App.class);
app.serviceABC.print();
}
您必須命名組件並按名稱自動接線:
@Component("A")
public class A implements IRepository<String,String> {...}
@Component("B")
public class B implements IRepository<Double,String> {...}
[...]
@Autowired
@Qualifier("B")
private IRepository repo;
看來您事先並不知道將需要IRepository
接口的哪種實現。 您將在運行時知道這一點。 在這種情況下,這是Factory模式的典型情況,在這種情況下,您將擁有一個IRepositoryFactory
,該方法將具有按類型檢索特定實現的方法(例如IRepositoryFactory.getInstance(String type);
因此,在ServiceABC
您可以使用IRepository
來獲取運行時使用特定的bean。因此,Factory模式可能是您問題的答案。我還寫了一篇文章來處理此類問題,並提出了自我填充Factory的想法(使用提供此類實用程序的開源庫)。文章鏈接: 在Spring框架中非侵入式訪問“孤立” Bean
這樣的東西?
@Controller
public class RepositoryFactory {
@Autowired
private IRepository<String, String> a;
@Autowired
private IRepository<Double, String> b;
public IRepository getRepository(String className) {
if(className.equalsIgnoreCase("a")) {
return a;
} else if(className.equalsIgnoreCase("b")) {
return b;
}
return null;
}
}
@Service
public class ServiceABC {
@Autowired
private RepositoryFactory repositoryFactory;
public void print(String className){
repositoryFactory.getRepository(className).print();
}
}
@Controller
public class App {
@Autowired
private ServiceABC serviceABC;
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext("asd");
App app = ctx.getBean(App.class);
app.serviceABC.print(A.class.getSimpleName());
}
}s
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.