Java Spring中的多个实现
我有TopicGenerator接口:Java Spring中的多个实现,java,spring,spring-boot,dependency-injection,Java,Spring,Spring Boot,Dependency Injection,我有TopicGenerator接口: public interface TopicGenerator { File create(MultiValueMap params); boolean accept(MultiValueMap params); } 和3个实现: @RequiredArgsConstructor public class JavaTopicGenerator implements TopicGenerator { //implementation omm
public interface TopicGenerator {
File create(MultiValueMap params);
boolean accept(MultiValueMap params);
}
和3个实现:
@RequiredArgsConstructor
public class JavaTopicGenerator implements TopicGenerator {
//implementation ommited for readability
@RequiredArgsConstructor
public class PhpTopicGenerator implements TopicGenerator {
//implementation ommited for readability
@RequiredArgsConstructor
public class CppTopicGenerator implements TopicGenerator {
//implementation ommited for readability
现在我试着根据我的参数使用它们,这就是为什么我创建了特殊的TopicFacade
@RequiredArgsConstructor
public class TopicFacade {
@NonNull
private final TopicService topicService;
@NonNull
private final List<TopicGenerator> topicGenerators;
public void generate(MultiValueMap<String, String> params, HttpServletResponse response) {
for (TopicGenerator topicGenerator : topicGenerators) {
if (topicGenerator.accept(params)) {
File tempFile = topicService.generate(params);
//do something else.
}
}
}
}
@RequiredArgsConstructor
公共类主题外观{
@非空
私人最终TopicService TopicService;
@非空
私人最终清单主题生成器;
public void generate(多值映射参数,HttpServletResponse){
用于(主题生成器主题生成器:主题生成器){
if(主题生成器接受(参数)){
File tempFile=topicService.generate(参数);
//做点别的。
}
}
}
}
在我的主题服务中,我有:
@Service
@RequiredArgsConstructor
public class TopicServiceImpl implements TopicService {
@NonNull
private final List<TopicGenerator> reportGenerators;
public File generate(MultiValueMap params) {
for (TopicGenerator topicGenerator : topicGenerators) {
if (topicGenerator.create(params)) {
return topicGenerator.export(params);
}
}
@服务
@所需参数构造函数
公共类TopicServiceImpl实现TopicService{
@非空
私人最终名单;
公共文件生成(多值映射参数){
用于(主题生成器主题生成器:主题生成器){
if(主题生成器创建(参数)){
返回topicGenerator.export(参数);
}
}
我得到一个错误,比如:
原因:org.springframework.beans.factory.unsatifiedpendencyException:创建名为“topicServiceImpl”的bean时出错:通过字段“topicGenerators”表示的未满足的依赖项;嵌套异常为org.springframework.beans.factory.nosuchbeandeDefinitionException:没有可用的“java.util.List”类型的合格bean:应为至少1个符合autowire候选项资格的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true)}
(早些时候,当我使用字段注入而不是构造函数时,我能够在3个实现中的一个实现之前添加
@Service
,代码正在工作,但这不是我想要的)使用限定符注释。
然后,您的Facade可以拥有所有这些实现,并且您有一个方法,该方法将根据您的条件返回特定的实现
然后在自动关联所有依赖项后初始化列表。
@Service//尝试使用注释。
公共类主题外观{
@自动连线
@限定词(“服务1”)
私人最终主题服务主题服务1;
//…其他服务也一样。
@自动连线
@限定词(“ServiceN”)
私人最终TopicService TopicService;
//在post构造中初始化它,并将所有服务放在那里。
@非空
private final List topicGenerators=new ArrayList();
@施工后
public void initTopicGenerators()引发异常{
topicGenerators.add(topicService1);
//等等。
topicGenerators.add(TopicService);
}
public void generate(多值映射参数,HttpServletResponse){
对于(ReportGenerator ReportGenerator:ReportGenerator){
if(reportGenerator.accept(参数)){
File tempFile=topicService.generate(参数);
//做点别的。
}
}
}
}
使用限定符注释。
然后,您的Facade可以拥有所有这些实现,并且您有一个方法,该方法将根据您的条件返回特定的实现
然后在自动关联所有依赖项后初始化列表。
@Service//尝试使用注释。
公共类主题外观{
@自动连线
@限定词(“服务1”)
私人最终主题服务主题服务1;
//…其他服务也一样。
@自动连线
@限定词(“ServiceN”)
私人最终TopicService TopicService;
//在post构造中初始化它,并将所有服务放在那里。
@非空
private final List topicGenerators=new ArrayList();
@施工后
public void initTopicGenerators()引发异常{
topicGenerators.add(topicService1);
//等等。
topicGenerators.add(TopicService);
}
public void generate(多值映射参数,HttpServletResponse){
对于(ReportGenerator ReportGenerator:ReportGenerator){
if(reportGenerator.accept(参数)){
File tempFile=topicService.generate(参数);
//做点别的。
}
}
}
}
可以定义列表类型的bean,如下所示:
@Configuration
public class AppConfig {
@Autowired
private TopicGenerator cppTopicGenerator;
@Autowired
private TopicGenerator phpTopicGenerator;
@Autowired
private TopicGenerator javaTopicGenerator;
@Bean
public List<TopicGenerator> topicGeneratorList()
{
return Arrays.asList(cppTopicGenerator, phpTopicGenerator, javaTopicGenerator);
}
}
@配置
公共类AppConfig{
@自动连线
私人主题生成器;
@自动连线
私有主题生成器;
@自动连线
私有主题生成器javaTopicGenerator;
@豆子
公共列表主题生成器列表()
{
返回Arrays.asList(cppTopicGenerator、phpTopicGenerator、javaTopicGenerator);
}
}
这样,您的原始代码应该可以正常工作
bean可以以各自的类名的形式引用。例如,cpptoicGenerator将引用类cpptoicGenerator.java的bean。尽管使用@Qualifier更清楚是一种好的做法。可以定义类型为List
的bean,如下所示:
@Configuration
public class AppConfig {
@Autowired
private TopicGenerator cppTopicGenerator;
@Autowired
private TopicGenerator phpTopicGenerator;
@Autowired
private TopicGenerator javaTopicGenerator;
@Bean
public List<TopicGenerator> topicGeneratorList()
{
return Arrays.asList(cppTopicGenerator, phpTopicGenerator, javaTopicGenerator);
}
}
@配置
公共类AppConfig{
@自动连线
私人主题生成器;
@自动连线
私有主题生成器;
@自动连线
私有主题生成器javaTopicGenerator;
@豆子
公共列表主题生成器列表()
{
返回Arrays.asList(cppTopicGenerator、phpTopicGenerator、javaTopicGenerator);
}
}
这样,您的原始代码应该可以正常工作
bean可以在各自的类名中引用。例如,cppTopicGenerator将引用类cppTopicGenerator.java的bean。尽管使用@Qualifier更清楚是一种好的做法。在哪里cppTopicGenerator
等实际上声明为bean?我只看到cla