如何在运行时动态更改依赖项

时间:2019-12-19 00:47:25

标签: java spring

我是一名春季开发人员。

在开发过程中,需要动态更改依赖关系。

这是模块B发生故障时调用的模块A。

由于A和B模块是调用不同API的相似API,所以我用Interface创建了一个抽象并将其注入到使用其依赖项的位置。

界面和实现如下所示。

public interface BookService {
    <T> Optional <ResponseEntity <T >> findBookListByQuery (BookSearchRequestUriVariables variables, Class <T> clazz);
}
@ Slf4j
@Service
@Primary
public class KakaoBookService implements BookService {
    @Override
    public <T> Optional <ResponseEntity <T >> findBookListByQuery (BookSearchRequestUriVariables variables, Class <T> clazz) {
        try {
            ResponseEntity <T> exchange = restTemplate.exchange (kakaoProperties.getBookSearchURL (),
                                                               HttpMethod.GET,
                                                               new HttpEntity (httpHeaders),
                                                               clazz,
                                                               variables.getUriVariables ());
            return Optional.ofNullable (exchange);
        } catch (Exception e) {
            log.info ("findBookListByQuery exception: {}", e.getMessage ());
            return Optional.empty ();
        }
    }
}
@Service
public class NaverBookService implements BookService {

@Override
    public <T> Optional <ResponseEntity <T >> findBookListByQuery (BookSearchRequestUriVariables variables, Class <T> clazz) {
        changeKakaoVariablesToNaverVariables (variables);
        return Optional.of (restTemplate.exchange (url, HttpMethod.GET, new HttpEntity (httpHeaders), clazz, variables.getUriVariables ()));
    }

    private BookSearchRequestUriVariables changeKakaoVariablesToNaverVariables (BookSearchRequestUriVariables variables) {
        Map <String, String> uriVariables = variables.getUriVariables ();

        uriVariables.put ("page", String.valueOf ((Integer.parseInt (variables.getUriVariables (). get ("page")) * 10) + 1));

        String sort = variables.getUriVariables (). Get ("sort");
        if (sort.equals ("accuracy")) sort = "sim";
        else if (sort.equals ("latest")) sort = "date";
        uriVariables.put ("sort", sort);

        return variables;
    }
}

实际使用位置如下。首先要做的是调用kakao API。如果有错误,请调用Naver API。

public BookSearchKakaoResponse findBookListByQuery (BookSearchRequestUriVariables variables) {

        saveToBookHistory (getJwtMember (). getMemberName (), variables.getUriVariables (). get ("query"));
        Optional <ResponseEntity <BookSearchKakaoResponse >> bookListByKakao = kakaoBookService.findBookListByQuery (variables, BookSearchKakaoResponse.class);

        if (! bookListByKakao.isPresent ()) {// call NAVER API
            return naverBookService.findBookListByQuery (...);
        }
        return bookListByKakao.get (). getBody ();
    }

我有kakaoBookService,我想将naverBookServicebookService合并。

如果调用kakao API的模块失败,我想将调用naver API的模块注入bookService。

请告诉我该怎么做。

我认为根据依赖性反转原则和开放式封闭原则将它们结合起来是一个好主意。

请让我知道我正在考虑的方向是否是代码设计问题。

谢谢。

1 个答案:

答案 0 :(得分:1)

您可以使用@Qualifier批注实现相同的目的。当提供给您bean时,容器将自动装配所有依赖项。您可以根据用例使用正确的服务

@Slf4j
@Service
@Primary
@Qualifier("kakao")
public class KakaoBookService implements BookService {}


@Service
@Qualifier("naver")
public class NaverBookService implements BookService {}

现在将两个bean自动连接到使用它的服务。

@Autowired @Qualifier("kakao")
    BookService kakaoBookService;

@Autowired @Qualifier("naver")
    BookService naverBookService;

尽管可以根据条件从应用程序上下文中动态获取bookService bean,但是自动装配依赖关系是一种更清洁的方法。