Я столкнулся со следующей проблемой, объединяющей дженерики 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': сбой вызова метода init;Вложенное исключение - java.lang.ClassCastException: SuperType не может быть приведен к SubType
.,.
[testng] Вызвано java.lang.ClassCastException: SuperType не может быть приведен к SubType
[testng] в SomeObj.method (SomeObj.java:22)
[testng] в B.setValues (B.java:63)
[testng] в ConfigInfo.init (ConfigInfo.java:64)
[testng] Причина: