我有TopicGenerator接口:
service_type_id
以及3种实现方式:
UPDATE customer_service_types cst
SET cst.created = (SELECT created
FROM customer_service_types cst2
WHERE cst.id = (cst2.id - 1) AND cst2.service_type_id <> 3
)
WHERE cst.service_type_id = 3;
现在我要尝试的是根据我的参数使用它们,这就是为什么我创建了特殊的TopicFacade。
public interface TopicGenerator {
File create(MultiValueMap params);
boolean accept(MultiValueMap params);
}
我在TopicServiceImpl上的位置:
@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
我收到如下错误:
@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.
}
}
}
}
(在我使用字段注入而不是构造函数时,我能够在3个实现之一之前添加@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);
}
}
,并且代码正在工作于该单个实现上,但是这不是我想要的)
答案 0 :(得分:2)
可以定义List<TopicGenerator>
类型的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);
}
}
有了这个,您的原始代码应该可以正常工作。
可以在camelCase中使用其各自的类名来引用Bean。例如cppTopicGenerator将引用类CppTopicGenerator.java的bean。尽管使用@Qualifier更加清晰是一种很好的做法。
答案 1 :(得分:0)
使用限定符注释。 https://www.tutorialspoint.com/spring/spring_qualifier_annotation.htm
https://stackoverflow.com/a/40844528/4587961
然后,您的Facade可以具有所有这些实现。并且您有一种方法,可以根据您的情况返回特定的实现。
然后自动装配所有依赖项后初始化列表。 https://stackoverflow.com/a/8519295/4587961
@Service // Try and play around with annotations.
public class TopicFacade {
@Autowired
@Qualifier("Service1")
private final TopicService topicService1;
//... The same stuff for other services.
@Autowired
@Qualifier("ServiceN")
private final TopicService topicServiceN;
//Initialize this in the post construct and put all your services there.
@NonNull
private final List<TopicGenerator> topicGenerators = new ArrayList();
@PostConstruct
public void initTopicGenerators() throws Exception {
topicGenerators.add(topicService1);
//And others.
topicGenerators.add(topicServiceN);
}
public void generate(MultiValueMap<String, String> params, HttpServletResponse response) {
for (ReportGenerator reportGenerator : reportGenerators) {
if (reportGenerator.accept(params)) {
File tempFile = topicService.generate(params);
//do something else.
}
}
}
}