Spring的多种实现

时间:2018-11-14 13:55:04

标签: java spring spring-boot dependency-injection

我有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); } } ,并且代码正在工作于该单个实现上,但是这不是我想要的)

2 个答案:

答案 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.
            }
        }
    }
}