I got Object coming in a REST web service controller's
web method which is locally initialized.
@RequestMapping(method = RequestMethod.POST,value = "/test",headers="Accept=*/*")
public @ResponseBody ModelAndView computeDetails(@RequestBody RequestObj reqObj, ModelMap model) {
System.out.println(reqObj.getcode());
return new ModelAndView("responsedetails", "object", reqObj);
}
This RequestObj object holds the key code
to instantiate dependency using factory.
Different codes classes have been defined which implement BaseCode Interface.
How can I use factory method to instantiate particular code class based on code value coming in as BaseCode type in my service bean?
Any idea? Thanks in advance.
What I usually do in such cases is:
Spring
's bean getBaseCode(String code)
in the factory (please note: String
here stands for code type, so use the actual code type if not String
getBaseCode
returning the BaseCode
interface while constructing the real implementation execute
method in BaseCode
, use the getBaseCode
method into the controller to get the real collaborator and then call the execute
method to perform the actual action
Ignoring the first point (which I think you can easily looking at any Spring tutorial) the factory will be something like
public class BaseCodeFactory {
public BaseCode getBaseCode(String code) {
if(code.equals("something")) return new ThisBaseCodeImpl();
else //and so on
}
}
while computeDetails
becomes similar to:
@RequestMapping(method = RequestMethod.POST,value = "/test",headers="Accept=*/*")
public @ResponseBody ModelAndView computeDetails(@RequestBody RequestObj reqObj, ModelMap model) {
//...
factory.getBaseCode(reqObj.getcode()).execute();
//...
}
As a side note, I will not go for names like the one I choose here, I suggest you to look for something more significative in your domain ( BaseCode
has no meaning for example), take this snippets just as a directive.
Base on OP comment . If you have ThisBaseCodeImpl
which makes use of other Spring bean you can
@Configurable
so, when you use new ThisBaseCodeImpl(/*args if you like*/)
its bean are instantiated by Spring. I don't personally like this solution since, in my opinion, it pollutes the code with hidden Spring's bean. On the other hand is quite flexible, since it allows you to manage both runtime constructor arguments and Spring beans ThisBaseCodeImpl
to the Spring context and change the factory, so that a collaborator for ThisBaseCodeImpl
is injected into it. 1st point example:
@Configurable
public class ThisBaseCodeImpl {
@Resource
private Bean bean;
}
2nd point example:
public class BaseCodeFactory {
@Resource
ThisBaseCodeImpl thisBaseCodeImpl;
public BaseCode getBaseCode(String code) {
if(code.equals("something")) return thisBaseCodeImpl;
else //and so on
}
}
I'm not sure if I understood your problem well, but in general spring dependencies have nothing to do here. Just write custom Factory class and return BaseCode implemetation depending on the reqObj.getcode().
I did it this way -
Make your factory as ServletContextAware
in a way to get the currentContext. And define getInstance method as
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
ctx.getBean(classNameToBeInstantiated);
Define your bean's inheritance in spring context so that Spring injects its dependencies.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.