У меня был контроллер с 4 очень похожими методами, который вызывал API на удаленном сервере для выполнения различных действий с разными типами пользователей. Что изменилось между этими вызовами API, так это только конечная точка и некоторые параметры.
Таким образом, все эти 4 метода вызвали службы с очень похожим кодом: они получили токен с сервера, задали параметры, возвратили ответ API. Поскольку дополнительные действия будут добавлены позже , я решил использовать создание ServiceFactory с использованием шаблона Factory Method и использовать шаблон Template на сервисах, чтобы избежать дублирования кода.
Моя проблема в том, что для того, чтобы фабрика автоматически подключала сервисы, она должна быть связана с ними, я должен @Autowire
каждую реализацию. Есть ли лучшее решение?
Вот код, который у меня есть:
Контроллер покоя
@RestController
public class ActionController {
@Autowired
private SsoService ssoService;
// this is the factory
@Autowired
private ServiceFactory factory;
@PostMapping("/action")
public MyResponse performAction(@RequestBody MyRequest request, HttpServletRequest req) {
// template code (error treatment not included)
request.setOperator(ssoService.getOperator(req));
request.setDate(LocalDateTime.now());
return serviceFactory.getService(request).do();
}
}
Сервисный завод
@Component
public class ServiceFactory {
@Autowired private ActivateUserService activateUserService;
@Autowired private Action2UserType2Service anotherService;
//etc
public MyService getService(request) {
if (Action.ACTIVATE.equals(request.getAction()) && UserType.USER.equals(request.getUserType()) {
return activateUserService;
}
// etc
return anotherService;
}
}
Сервисная база, реализующая интерфейс MyService
public abstract class ServiceBase implements MyService {
@Autowired private ApiService apiService;
@Autowired private ActionRepository actionRepository;
@Value("${api.path}") private String path;
@Override
public MyResponse do(MyRequest request) {
String url = path + getEndpoint();
String token = apiService.getToken();
Map<String, String> params = getParams(request);
// adds the common params to the hashmap
HttpResult result = apiService.post(url, params);
if (result.getStatusCode() == 200) {
// saves the performed action
actionRepository.save(getAction());
}
// extracts the response from the HttpResult
return response;
}
}
Реализация сервиса (есть 4)
@Service
public class ActivateUserService extends ServiceBase {
@Value("${api.user.activate}")
private String endpoint;
@Override
public String getEndpoint() {
return endpoint;
}
@Override
public Map<String,String> getParams(MyRequest request) {
Map<String, String> params = new HashMap<>();
// adds custom params
return params;
}
@Override
public Action getAction() {
return new Action().type(ActionType.ACTIVATED).userType(UserType.USER);
}
}