我正面临结合Java泛型和Spring的以下问题。它本质上涉及要求抽象一些在运行时确定的组件。我有一个包含自动连接字段的类,该字段是一个接口,该接口由一个采用通用类型的类实现,然后由随后的调用者序列使用。它需要在运行时使用该泛型的特定实现实例化。这是场景。
public interface A {
void setValues(Object obj);
}
@Component
@Scope("prototype")
public class SuperType {
// some fields and methods
}
public interface ObjType<T extends SuperType> {
void method(T values);
}
@Component
public class B<T extends SuperType> implements A {
// field objType that requires T
@Autowired
private ObjType<T> objType;
public void setValues(Object obj) {
// sets values of T through a method that can be overridden
T values = getValues(obj);
// calls objType's method
objType.method(values);
}
protected T getValues(Object obj) {
// some values being set here for supertype and being cast to T
SuperType s = new SuperType();
return (T) s;
}
现在更具体的实现-
@Component
@Scope("prototype")
public class SubType extends SuperType {
// sub type specific fields and methods
}
@Component
public class SomeObj implements ObjType<SubType> {
public void method(SubType values) {
// some implementation
}
}
它实际上是如何被调用和实例化的
@Component
public class ConfigInfo {
// some fields
@Autowired
private A a;
@PostConstruct
private void init() {
a.setValues(this);
}
}
@Test
public class TestClass extends SomeSpringTestBase {
@Autowired
private ConfigInfo info;
}
我尝试通过Spring上下文配置提供更具体的实现,并将此配置包含在测试库中
@Configuration
public class SpringTestConfiguration {
@Autowired
private ApplicationContext applicationContext;
@Bean
@Primary
public B<SubType> getA() {
B<SubType> b = new B<SubType>();
return b;
}
@Bean
@Primary
public SomeObj getObjType() {
SomeObj obj = new SomeObj();
return obj;
}
}
本质上,我需要在运行时将B<SubType>
的实例使用实现A
,将SomeObj
的实例用于ObjType<T>
的实例,但是这需要由Sprong注入。在这一点上,我不确定是否使用了泛型部分或Spring部分,或两者都使用不正确。这是我得到的错误。
[testng]由以下原因引起: org.springframework.beans.factory.BeanCreationException:错误 创建名称为“ ConfigInfo”的bean:初始化方法的调用 失败嵌套的异常是java.lang.ClassCastException:SuperType 无法转换为SubType
。 。[testng]由java.lang.ClassCastException引起:无法将SuperType强制转换为SubType
[testng] at SomeObj.method(SomeObj.java:22)
[testng] at B.setValues(B.java:63)
[testng]位于ConfigInfo.init(ConfigInfo.java:64)
[testng]原因: