我正在尝试使用Spring IoC这样的接口:
public interface ISimpleService<T> {
void someOp(T t);
T otherOp();
}
Run Code Online (Sandbox Code Playgroud)
Spring可以根据泛型类型参数T提供IoC吗?我的意思是,像这样:
public class SpringIocTest {
@Autowired
ISimpleService<Long> longSvc;
@Autowired
ISimpleService<String> strSvc;
//...
}
Run Code Online (Sandbox Code Playgroud)
当然,我上面的例子不起作用:
expected single matching bean but found 2: [serviceLong, serviceString]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:243)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:957)
Run Code Online (Sandbox Code Playgroud)
我的问题:是否可以提供类似的功能,只需对接口或实现类进行最少的修改?我知道我可以使用@Qualifiers,但我希望尽可能简单.
我有一堆实现类型的存储库bean Repository<T ? extends Node>.现在我可以从用户那里获得一个随机节点列表,我想为每个节点获取相应的存储库.从Spring 4.0RC1开始,我们可以像这样自动装配存储库:
@Autowired Repository<SomeNode> someNodeRepository;
Run Code Online (Sandbox Code Playgroud)
如此处所述.
这工作正常,但我的问题是如何基于泛型类型动态地执行此操作.
我想做的是:
public <T extends Node> T saveNode(T node) {
Repository<T> repository = ctx.getBean(Repository.class, node.getClass());
return repository.save(node);
}
Run Code Online (Sandbox Code Playgroud)
其中第二个参数是泛型类型.这当然不起作用,虽然它编译.
我找不到任何关于此的文件.
如果我们提供足够的泛型信息,像 Jackson 这样的库可以从 JSON 创建对象。
在杰克逊,我们可以做到
Class<?>[] parameterTypes;
JavaType type = objectMapper.getTypeFactory().constructParametricType(ObjectClass, parameterTypes);
objectMapper.readValue(json, type);
Run Code Online (Sandbox Code Playgroud)
在 java 中,可以通过多种方式定义泛型类,例如一个泛型类具有另一个泛型类,并且可以具有另一个泛型类,为了简单说明,考虑这三个类。
public class MultiLevelGenericTestData<T, V> {
private GenericTestData<T> tGenericTestData;
private GenericTestData<V> vGenericTestData;
}
public class MultiGenericTestData<K, V> {
private K key;
private V value;
}
public class MultiGenericTestDataSameType<T> {
private GenericTestData<T> genericTestData;
private MultiGenericTestData<T, T> multiGenericTestData;
}
Run Code Online (Sandbox Code Playgroud)
我知道类型擦除和其他事情,但有没有办法识别类型 T, V从 的对象中MultiLevelGenericTestData?
我想到的一种方法是检查泛型类型并查看它们的名称并检查所有字段,直到找到所有类型。一旦我们遇到具有相同泛型类型的多个字段的情况,这很快就会变得棘手,例如在MultiGenericTestDataSameType,我们应该只得到一种泛型类型。
// This method should find all type's class names in the list
// that can be …Run Code Online (Sandbox Code Playgroud) 对于我的应用程序,我有一个Scale接口和多个实现该接口的类,例如NormalizedScale,LogScale等。在我的一个服务中,我需要创建许多 Scales,并且我想使用 Spring 来定义它应该创建的 Scale 的哪个实现. 我将如何实施这样的事情?
——
我想创建一个工厂ScaleFactory,就像在抽象工厂模式中一样,我可以调用它ScaleFactory.getScale()来获取我在 Spring XML 中配置的任何实现的规模:
class ScaleFactory {
Class<? extends Scale> scaleImplClass;
public static Scale getScale() {
return scaleImplClass.newInstance();
}
}
Scale myScale = ScaleFactory.getScale();
Run Code Online (Sandbox Code Playgroud)
但是使用这种方法,我如何配置 ScaleFactory 应该从 Spring XML 使用哪个实现?
——
另一种方法是制作ScaleFactorya @Service,然后将 ScaleFactory 自动装配到我的服务中:
@Autowired
ScaleFactory scaleFactory;
...
Scale myScale = scaleFactory.getScale();
Run Code Online (Sandbox Code Playgroud)
然后我可以使用 ScaleFactory 中的自动装配属性来定义scaleImplClass. 但这似乎很奇怪,因为我的工厂也是一个服务,而且我有一个该工厂的实例。
——
另一种方法是Class scaleImplementationClass在我的服务中使用该属性而不是 ScaleFacotry 并像这样使用 ScaleFactory: …
我在以下问题中尝试过这个解决方案,但在我的情况下没有一个工作:
@Configuration
@EnableWebMvc
@ComponentScan("myapp.framework.export")
public class WebConfig extends MyAppWebConfig {
@Override
public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
super.configureContentNegotiation(configurer);
}
@Override
public void configureMessageConverters(final List<HttpMessageConverter<?>> converters) {
super.configureMessageConverters(converters);
}
}
Run Code Online (Sandbox Code Playgroud)
错误:
INFO: Initializing Spring FrameworkServlet 'services-rest'
2017-04-11 15:25:52,774|localhost-startStop-1|NO_TID|NO_USER|ERROR|org.springframework.web.servlet.DispatcherServlet.initServletBean|Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xlsHttpMessageConverter': Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'myapp.framework.export.ExportXlsModelService<?>[]' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.annotation.Resource(shareable=true, lookup=, name=, description=, authenticationType=CONTAINER, type=class …Run Code Online (Sandbox Code Playgroud) 这感觉就像一个愚蠢的问题,甚至可能是一个副本(我看了,但找不到它).
但是,如果在类型安全方面,我是如何做到这一点的?
ArrayList<String> myList = applicationContext.getBean( ArrayList<String>.class );
Run Code Online (Sandbox Code Playgroud)