Spring中是否有一種機制爲泛型bean構造的自動化提供了一種方法?Spring通用bean工廠
爲,例如,如果我有一個類定義,如:
class Foo<T> {
private final T type;
...
}
和依賴性,如:
@Autowired
private Foo<String> foo;
我想使用在Spring中的一些機制提供以某種形式, T從依賴關係定義(在上面的例子中,字符串),並提供了一種自動創建實例的方法?
Spring中是否有一種機制爲泛型bean構造的自動化提供了一種方法?Spring通用bean工廠
爲,例如,如果我有一個類定義,如:
class Foo<T> {
private final T type;
...
}
和依賴性,如:
@Autowired
private Foo<String> foo;
我想使用在Spring中的一些機制提供以某種形式, T從依賴關係定義(在上面的例子中,字符串),並提供了一種自動創建實例的方法?
通過在你的Spring配置定義的:
@Bean
public Foo<String> foo() {
return new Foo<>("bar");
}
或替代的價值,你可以指定類型:
@Bean
public Foo<String> foo() {
return new Foo<>(String.class);
}
如果你使用Spring啓動,您可以添加@ConditionalOnProperty
或@ConditionalOnBean
動態化bean實例。
(更新)如果您想避免申報,您應該延長DefaultListableBeanFactory
和ApplicationContext
。這裏是春天引導工作的例子:
@Controller
@EnableAutoConfiguration
public class BeanFactoryTest {
public static void main(String[] args) throws Exception {
SpringApplication app = new SpringApplication(BeanFactoryTest.class);
app.setApplicationContextClass(CustomAppContext.class);
app.run(args);
}
@Autowired
private Foo<String> foo1;
@Autowired
private Foo<String> foo2;
@Autowired
private Foo<Integer> foo3;
@PostConstruct
public void initialize() {
System.out.println(foo1); // prints [email protected]
System.out.println(foo2); // prints [email protected]
System.out.println(foo3); // prints [email protected]
}
public static class CustomAppContext extends AnnotationConfigApplicationContext {
public CustomAppContext() {
super(new CustomBeanFactory());
}
}
public static class CustomBeanFactory extends DefaultListableBeanFactory {
@Override
protected Map<String, Object> findAutowireCandidates(String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
Map<String, Object> map = super.findAutowireCandidates(beanName, requiredType, descriptor);
if (Foo.class.isAssignableFrom(requiredType)) {
ResolvableType type = ResolvableType.forField(descriptor.getField());
ResolvableType genericType = type.getGeneric(0);
Class<?> genericTypeRaw = genericType.getRawClass();
boolean hasInstance =
map.values()
.parallelStream()
.map(Foo.class::cast)
.map(Foo::getType)
.filter(genericTypeRaw::isAssignableFrom)
.findFirst()
.isPresent();
if (!hasInstance) {
super.registerResolvableDependency(requiredType, new Foo<>(genericTypeRaw));
map = super.findAutowireCandidates(beanName, requiredType, descriptor);
}
}
return map;
}
}
public static class Foo<T> {
private final Class<T> type;
public Foo(Class<T> type) {
this.type = type;
}
public Class<T> getType() {
return type;
}
}
}
我添加了一個實現。工作,但可以優化。 –