我使用最新版本的Spring,当我尝试两次注入相同的泛型类型并且泛型类型的实现使用缓存时,我遇到了启动错误。
以下是我可以创建的用于复制错误的最简单示例。
// build.gradle dependencies
dependencies {
compile 'org.springframework.boot:spring-boot-starter'
compile 'org.springframework.boot:spring-boot-starter-web'
}
// MyApplication.java
@SpringBootApplication
@EnableCaching
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public CacheManager cacheManager() {
return new ConcurrentMapCacheManager();
}
}
// HomeController.java
@RestController
@RequestMapping(value = "/home")
public class HomeController {
@Autowired
public HomeController(
GenericService<String> s1,
GenericService<String> s2, // <-- Notice GenericService<String> twice
GenericService<Integer> s3
) {}
}
// GenericService.java
public interface GenericService<T> {
public T aMethod();
}
// IntegerService.java
@Service
public class IntegerService implements GenericService<Integer> {
@Override
@Cacheable("IntegerMethod")
public Integer aMethod() {
return null;
}
}
// StringService.java
@Service
public class StringService implements GenericService<String> {
@Override
@Cacheable("StringMethod")
public String aMethod() {
return null;
}
}
这个编译很好,但是当我运行应用程序时,我收到以下错误:
No qualifying bean of type [demo.GenericService] is defined: expected single matching bean but found 2: integerService,stringService
我还没有尝试使用限定符,但我猜这将是一种解决方法。发布之后我会尝试一下。理想情况下,我希望通过自动装配泛型和缓存来集成开箱即用的功能。我做错了什么,或者我能做些什么让它运转起来?
谢谢!
答案 0 :(得分:0)
如果您不想在构造函数中使用@Qualifier并仍然使用接口,则可以只为服务声明添加一个值。
@Service(value = "integerService")
public class IntegerService implements GenericService<Integer> {
@Override
@Cacheable("IntegerMethod")
public Integer aMethod() {
return 42;
}
}
@Service(value = "stringService")
public class StringService implements GenericService<String> {
@Override
@Cacheable("StringMethod")
public Integer aMethod() {
return 42;
}
}
为了确定,我使用Spring-Boot创建了一个项目,编译并运行它。所以上面应该有效。它与您已经在做的事情基本相同,但输入次数较少。
我之前的回答(在修改之前)是做这样的事情:
// HomeController.java
@RestController
@RequestMapping(value = "/home")
public class HomeController {
@Autowired
public HomeController(
StringService s1,
StringService s2,
IntegerService s3
) {}
}
但你必须不实现接口才能使其发挥作用。