[英]Spring 4 dependency injection for abstract generic classes do not work
我有X
和Y
基类,它们具有多个实现。 但是,每种参数化类型只有一个实现,因此@Autowired
应该能够确定需要哪个子类。
在将第二个参数U
添加到基类X
和Y
(并因此添加到它们的所有子类)之前,这实际上是可行的。 但是添加之后,这是Spring初始化期间的错误:
org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为'myApp'的bean时出错:通过字段'x1'表示的不满足的依赖关系; 嵌套的异常是org.springframework.beans.factory.UnsatisfiedDependencyException:创建名称为'xImpl1'的bean时出错:通过字段y表示的不满足的依赖关系; 嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的类型为“ test.Y>”的合格Bean:期望至少有1个有资格作为自动装配候选的Bean。 依赖项注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
github(maven项目)中的代码: https : //github.com/kevincentius/spring-di-abstract-generic-problem/tree/master/spring-test
抽象的通用类X<T, U>
和Y<T, U>
互相引用:
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public abstract class X<T, U> {
protected T t;
protected U u;
@Autowired
protected Y<T, X<T, U>> y; // error when initializing xImpl1
// ...
}
Y
类知道实现类V
(例如XImpl1
)。 与X
相对,后者仅知道抽象类Y
,但不知道其实现类型(例如YImpl1
)。
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public abstract class Y<T, V extends X<T, ?>> {
protected T t;
protected V v;
// ...
}
Pojo课:
public class A {
// pojo
}
一个简单的界面:
public interface B {
// ...
}
这仅仅是子类的一个X
,但这是唯一的子类X
与参数化类型A
和B
(即唯一的子类X<A, B>
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class XImpl1 extends X<A, B> {
// ...
}
像上面一样Y<A, B>
的唯一实现。 尽管Y
其他实现具有不同的参数化类型。
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class YImpl1 extends Y<A, XImpl1> {
// ...
}
最后使用实现:
@Component
public class MyApp {
@Autowired
XImpl1 x1; // error
}
可能是有用的信息:
如果我将类X和Y设为非抽象类,则初始化错误消失了,但是即使XImpl1覆盖了X上的方法,在依赖项注入之后也不适用! 即在MyApp中,调用x1.something()实际上并不调用XImpl1的方法,而是调用X类的something()方法。
我可能在这里犯了一些错误,如果有人可以指出一些建议,我将感到非常高兴。 但是否则,似乎Spring仍然有一些局限性吗?
我不了解Spring的限制。 我建议简化。 不要再假设问题出在Spring:就是你。
我会说您的设计不必要地复杂。
我不知道这是一个例子还是您的真实代码。 您对泛型的命名和使用使它无法阅读和理解。 您已经从类层次结构中抽象出了所有理解。
这听起来像是应该优先于继承而不是继承的情况。 那只是我的意见。
@Autowire
构造函数时,我建议将@Qualifier
添加到参数列表中,并使用值精确说明要注入的bean。 如果您有几个由bean工厂管理的相同类型的bean,期望Spring会读懂您的想法是不合理的。 它无法选择自动接线。 只有您可以决定。
世界正朝着功能编程的方向发展,而不是面向对象。 我很想知道您是否可以通过使用lambdas和新的java.util.function包来对此进行改进。 您可能会获得更大的灵活性和更好的理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.