[英]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.