普通类型的Spring问题

its*_*sme 3 java generics spring

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

public class TestInj<S> {
    S elem;
    public S getElem() {
        return elem;
    }
    public void setElem(S elem) {
        this.elem = elem;
    }
}

@Component
public class First extends TestInj<String> {
    public First() {
        setElem("abc");
    }
}

@Component
public class Second extends TestInj<Integer> {
    public Second() {
        setElem(2);
    }
}



public class BaseTest<T> {
    @Autowired
    protected TestInj<T> test;

}

@Named
public class Test extends BaseTest<String> {
    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());
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Sea*_*oyd 7

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

不幸的是,它不是,Spring就是不行.在分析bean类,春天永远看起来下来,从它在哪里的层次结构.(在其他我希望将方法@Transactional放在实现子类的抽象超类和注释中的情况下,我已经反对这一点.)

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