Question

Below is my controller. My program generates an output, based on a form input. Across the project, there are multiple input forms, that generate the output object. So, the essential flow is the same. So I want a single multi-action controller that does all of that.

Challenges: 1. The service classes change. Although all services implement the same interface, and controller calls the same interface method. 2. The input objects change. Although the input objects do not have any methods other than setters, and getters. So I let them all implement an empty interface.

Questions:

  1. How do I change the qualifier, based on the path. Can I use path variables?

  2. Suppose the path has this value -> singleton. Then my corresponding bean names would be singletonService and singletonInput. I want to make a constant class that has stores this mapping information. So, can I call that from inside the qualifier, using some Spring Expression Language? Example, instead of Qualifier(variablePathName) -> Qualifier(getQualifierName['variablePathName']) Something like that?

  3. Please also clarify the theory behind this. From what I understand, beans are created, autowired before the Request are mapped... Does this mean that what I'm trying to achieve here is simply not possible. In that case, would you suggest making Controller-service pairs for handling each request, with basically the same code? But I feel there must be some way to achieve what I'm trying...

Code:

@Cotroller
@RequestMapping(value="/generate/{path}")
public class TestController {

    @Autowired
    @Qualifier(......)
    private IService service;

    @Autowired
    @Qualifier(......)
    IUserInput userInput;

    @RequestMapping(method = RequestMethod.POST)
    //Some handler method
}
Was it helpful?

Solution

You're right in that the autowiring is all done once up front (point 3). You wouldn't be able to achieve what you want using fields annotated @Autowired and @Qualifier - as these fields would always reference the same bean instance.

You may be better to ask Spring for the particular service bean by name - based on the path variable. You could do it within a single controller instance. For example:

@Cotroller
@RequestMapping(value="/generate/{path}")
public class TestController {

    @Autowired
    private ApplicationContext applicationContext;

    @RequestMapping(method = RequestMethod.POST)
    public String someHandlerMethod(@PathVariable String path) {
        IService service = (IService) applicationContext.getBean(path + "Service");
        IUserInput userInput = (IUserInput) applicationContext.getBean(path + "UserInput");

        // Logic using path specific IService and IUserInput
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top