首页 > 解决方案 > 如何在运行时动态更改依赖关系

问题描述

我是一名春季开发人员。

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

如果模块 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 的模块失败,我想在 bookService 中注入一个调用 naver API 的模块。

请告诉我该怎么办。

我认为根据依赖倒置原则和开放封闭原则将它们组合起来是一个好主意。

如果我正在考虑的方向是代码设计问题,请告诉我。

谢谢你。

标签: javaspring

解决方案


您可以使用 @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;

尽管可以在 condition 上从应用程序上下文中动态获取 bookService bean,但自动装配依赖项是一种更简洁的方法。


推荐阅读