普通类型的Spring问题

使用generics时,我遇到Spring问题。 以下代码描述了这个问题:

public class TestInj { S elem; public S getElem() { return elem; } public void setElem(S elem) { this.elem = elem; } } @Component public class First extends TestInj { public First() { setElem("abc"); } } @Component public class Second extends TestInj { public Second() { setElem(2); } } public class BaseTest { @Autowired protected TestInj test; } @Named public class Test extends BaseTest { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("conf-spring.xml"); context.refresh(); Test test = (Test) context.getBean("test", Test.class); System.out.println(test.test.getElem()); } } 

问题是,在类BaseTest中应该注入类First,因为它具有generics类型String。 但spring没有得到那个并且告诉我,有两种可能的自动assembly候选者。 原因是,spring忽略了generics。 是否有解决方案或解决方法?

Spring对于generics非常聪明,但是你的要求太高了。 Spring分析包含要注入的属性的类的generics,即BaseTest 。 但依赖性test的类型擦除是TestInj 。 只有子类Test提供了更多通用信息, 用于限制注入候选者。

对你来说不幸的是,它不是,Spring就是这样。 在分析bean类时,Spring永远不会从层次结构中查看层次结构。 (在其他我需要将方法放在抽象超类和@Transactional注释的实现子类的情况下,我已经反对这一点。)

因此,如果您需要该function,则必须为Spring的一个核心组件( AutowiredAnnotationBeanPostProcessor或其使用的辅助类之一)编写替代品。 由于Spring是以模块化方式设计的,所以如果你只提供一个子类,你应该能够做到这一点而不会破坏任何东西。 但是如果你不是绝对需要这个function,那么简单的答案是:“它不能那样工作”:-)

这是由于类型擦除。 看到:

http://download.oracle.com/javase/tutorial/java/generics/erasure.html

When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method. Type erasure enables Java applications that use generics to maintain binary compatibility with Java libraries and applications that were created before generics.

由于Spring DI容器在运行时工作,因此无法区分这些类型。