我有基类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个符合autowire资格的bean 候选人。依赖注释: {@ org.springframework.beans.factory.annotation.Autowired(所需=真)}
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
的{{1}}相反,而不是其实现类型(例如Y
)。
YImpl1
pojo课程:
@Component
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public abstract class Y<T, V extends X<T, ?>> {
protected T t;
protected V v;
// ...
}
一个简单的界面:
public class A {
// pojo
}
这只是public interface B {
// ...
}
的子类之一,但这是X
的唯一子类,参数化类型为X
和A
(即B
的唯一子类{1}}):
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> {
// ...
}
可能是有用的信息:
如果我将类X和Y设置为非抽象,则初始化错误消失,但即使XImpl1覆盖X上的方法,这也不适用于依赖注入之后!即在MyApp中,调用x1.something()实际上并不调用XImpl1的方法,而是调用X类的something()方法。
我可能在这里犯了一些错误,如果有人能指出一些问题,我会很高兴。但除此之外,看起来Spring仍然有一些局限性?
答案 0 :(得分:0)
我不知道Spring的限制。我建议简化。停止假设问题是Spring:就是你。
我会说你的设计不必要地复杂。
我不知道这是一个例子还是你的真实代码。您对泛型的命名和使用使得无法阅读和理解。你已经从这个类层次结构中抽象出所有的理解。
这听起来像组合应优先于继承的情况。这只是我的意见。
当你@Autowire
构造函数时,我建议在参数列表中添加一个@Qualifier
,其值明确指出你要注入的bean。如果你有几个由bean工厂管理的相同类型的bean,那么期望Spring会读你的想法是不合理的。它无法选择哪一个自动装配。只有你可以决定。
世界正朝着功能性编程的方向发展,远离面向对象。我很想知道您是否可以通过使用lambdas和新的java.util.function软件包来改进这一点。您可以获得更多的灵活性和更好的理解。