title: How to create a Simple Factory Pattern with autowired beans in Spring?
body: <p>I had a controller with 4 very similar methods, calling an API on a remote server to perform different actions on different types of users. What changed between these API calls are just the endpoint and some parameters.</p>
  
  <p>Therefore, these 4 methods all called services with very similar code: they got a token from the server, set the parameters, return the API's response. Since <em>more actions will be added later</em>, I decided to use create a ServiceFactory using the Factory Method pattern and use the Template pattern on the services to avoid code duplication.</p>
  
  <p>My problem is that in order for the factory to autowire the services, it needs to be coupled to them, I have to <code>@Autowire</code> every implementation. Is there a better solution?</p>
  
  <p>Here's the code I have so far:</p>
  
  <h1>Rest Controller</h1>
  
  <pre><code>@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();
    }
  }
  </code></pre>
  
  <h1>Service Factory</h1>
  
  <pre><code>@Component
  public class ServiceFactory {
  
    @Autowired private ActivateUserService activateUserService;
    @Autowired private Action2UserType2Service anotherService;
    //etc
  
    public MyService getService(request) {
      if (Action.ACTIVATE.equals(request.getAction()) &amp;&amp; UserType.USER.equals(request.getUserType()) {
        return activateUserService;
      }
      // etc
      return anotherService;
    }
  }
  </code></pre>
  
  <h1>Service Base, implementing the MyService interface</h1>
  
  <pre><code>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&lt;String, String&gt; 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;
    }
  }
  </code></pre>
  
  <h1>Service Implementation (there are 4)</h1>
  
  <pre><code>@Service
  public class ActivateUserService extends ServiceBase {
    @Value("${api.user.activate}")
    private String endpoint;
  
    @Override
    public String getEndpoint() {
      return endpoint;
    }
  
    @Override
    public Map&lt;String,String&gt; getParams(MyRequest request) {
      Map&lt;String, String&gt; params = new HashMap&lt;&gt;();
      // adds custom params
      return params;
    }
  
    @Override
    public Action getAction() {
      return new Action().type(ActionType.ACTIVATED).userType(UserType.USER);
    }
  }
  </code></pre>