2017-07-31 162 views
1

我有基类XY,其中有多个实现。但是,只有一个实现为每个参数化类型,因此@Autowired应该能够找出需要其子类。弹簧4依赖注入抽象泛型类不工作

在将第二个参数U添加到基类XY(从而添加到它们的所有子类)之前,这实际上起作用。但补充说,这里是春天初始化过程中的错误后:

org.springframework.beans.factory.UnsatisfiedDependencyException: 错误创建名为“对myApp”豆:不满意依赖 通过实地“X1”表示;嵌套的例外是 org.springframework.beans.factory.UnsatisfiedDependencyException: 错误创建名为“xImpl1”豆:不满意依赖 通过现场表示“Y”;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:否 类型'test.Y>' 可用的符合条件的bean:预计至少有1个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仅知道抽象类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与参数化类型的唯一子AB(即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仍然有一些限制?

回答

0

我不知道春天的限制。我建议简化。别假设问题是春天:就是你。

我会说你的设计不必要的复杂。

我不能说这是一个例子还是你的真实代码。您对泛型的命名和使用会导致无法阅读和理解。你已经从这个类层次中抽象出所有的理解。

这听起来像是一种情况,其中组合应该比继承更受欢迎。这只是我的看法。

当您@Autowire构造函数,我建议在参数列表中添加一个@Qualifier与一个值,确切地说明您希望注入哪个bean。如果你有几个相同类型的bean由你的bean工厂管理,那么期望Spring会阅读你的想法是不合理的。它不能选择自动装配哪一个。只有可以决定。

世界正朝着函数式编程的方向发展,远离面向对象。我很想知道你是否可以通过使用lambdas和新的java.util.function包改善这一点。您可能会获得更多灵活性和更好的理解。