我正在使用Spring 3.2.2并且想知道是否有一种方法可以按类类型注入bean而不显式给它们一个字符串名称。例如:
@Named
public MyClass{
}
@Named
public MyOtherClass extends MyClass{
}
@Named
public class Foo{
public void blah(){
MyClass myClass = context.getBean(MyClass.class);
}
}
这将产生:
org.springframework.beans.factory.NoUniqueBeanDefinitionException:没有定义[MyClass]类型的限定bean:期望的单个匹配bean但找到2:myClass,myOtherClass
有没有办法说“使用与类名完全匹配的那个”而不使用String名称?
换句话说,我不想这样做:
@Named("MyClass")...
@Named("MyOtherClass")...
MyClass myClass = context.getBean("MyClass");
谢谢!
答案 0 :(得分:1)
这是§ 5.4.5 of Spring manual在遇到非唯一依赖bean定义时建议的内容:
答案 1 :(得分:1)
例如,您可以执行以下操作:
@Named
public class Foo{
public void blah(){
MyClass myClass = getBean(MyClass.class);
}
private <T> T getBean(Class<T> type) {
return context.getBean(Introspector.decapitalize(type.getSimpleName()), type);
}
}
但使用@Inject
或@Autowire
时,这不起作用。
要在自动装配时强制进行严格的类匹配,您可以使用AutowireCandidateResolver
替换BeanFactory
上的默认BeanFactoryPostprocessor
,但似乎不是@Resource
好主意或@Qualify
可以解决NUBDE问题。
例如:(未经测试)
public class StrictClassAutowireCandidateResolver implements AutowireCandidateResolver {
@Override
public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
if (!bdHolder.getBeanDefinition().isAutowireCandidate()) {
return false;
}
if (descriptor == null) {
return true;
}
String className = null;
if (descriptor.getField() != null) {
className = descriptor.getField().getType().getName();
}
else if (descriptor.getMethodParameter() != null) {
className = descriptor.getMethodParameter().getParameterType().getName();
}
Class<?> clazz = null;
try {
clazz = Class.forName(className);
}
catch (Exception e) {
return false;
}
if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) {
// have no chances to be strict, let BeanFactory to find implementations.
return true;
}
return bdHolder.getBeanDefinition().getBeanClassName().equals(className);
}
@Override
public Object getSuggestedValue(DependencyDescriptor descriptor) {
return null;
}
}
答案 2 :(得分:0)
尝试在您的类上使用@Component(Service,Repository,Controller),并在注入bean时使用@Autowired。
编辑:我的不好,我没有太好地阅读这个问题。问题是你实际上有2个MyClass实例(因为MyOtherClass从MyClass扩展)。因此除了给出类名之外别无他法,或者你总是会得到NoUniqueBeanDefinitionExceptions。