Reputation: 2415
I have 2 class with 2 same URL mappings:
@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(@PathVariable(TOPIC_ID) Long topicId) {
...
}
//
@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodB(@PathVariable(TOPIC_ID) Long topicId) {
...
}
MethodB is in a class that is loaded dynamically. I want use methodA only if methodB is not available. If methodB is available the Spring uses only it. How can I do that.
Upvotes: 0
Views: 1617
Reputation: 148965
The spring way would be to have only one controller mapped to an URL, and to inject the dynamic class that actually does the job in it:
class A {
@Autowired(required = false)
class B b; // inject by Spring or by ... or not at all
...
@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(@PathVariable(TOPIC_ID) Long topicId) {
if (b != NULL) { // class B has been found and injected
return b.methodB(topicId)
}
// fallback ...
...
}
}
class B {
// NO @RequestMapping here !
public ModelAndView methodB(@PathVariable(TOPIC_ID) Long topicId) {
...
}
}
Upvotes: 1
Reputation: 3883
In spring, a controller object is a singleton bean in spring context, and the context is initialized during starting. So, if a class is dynamically loaded, the request mapping will not be applied. So you can not do what you said.
The solution above of ZeroOne is the only way I think.
Upvotes: 0
Reputation: 3171
It sounds really confusing to sometimes have the URL mapping come from one package and sometimes from another. Why don't you do as Ken Bekov suggested in a comment and have just one class where there's the URL mapping and have that class dynamically decide which implementation to use? So something like this:
@RequestMapping(value = "/topics/{id}", method = RequestMethod.GET)
public ModelAndView methodA(@PathVariable(TOPIC_ID) Long topicId) {
Class classWithMapping;
try {
classWithMapping = Class.forName("class.that.MayNotExist");
} catch(ClassNotFoundException cnfe) {
classWithMapping = MyDefaultClass.class;
}
// ....
}
...and then instantiate classWithMapping
using reflection or Spring's application context.
Upvotes: 1