Reputation: 983
I have a typed service interface:
public interface BaseArticleService<T extends BaseArticle> {
T getById(Long id);
}
And have two interfaces which extends it:
public interface AccArticleService extends BaseArticleService<AccArticle> {
}
public interface ExpArticleService extends BaseArticleService<ExpArticle> {
Long getCount();
}
Then I have a similar architecture for controllers:
public abstract class BaseArticleController<T extends BaseArticle> {
@Autowired
BaseArticleService<T> baseArticleService;
}
And:
@Controller
@RequestMapping(value = "/exp/articles")
public class ExpArticleController extends BaseArticleController<ExpArticle> {
}
@Controller
@RequestMapping(value = "/acc/articles")
public class AccArticleController extends BaseArticleController<AccArticle> {
}
Now if I want to get my ExpArticleService instance of the BaseArticleService that is injected in my BaseController, how can I achieve this?
If I do this:
public BaseArticleService<ExpArticle> getExpArticleService() {
return super.baseArticleService;
}
then I cannot call my getCount()
method like getExpArticleService().getCount()
And cannot do this neither:
public ExpArticleService getExpArticleService() {
return super.baseArticuloService;
}
So what's the solution? Maybe inject another ExpArticleService
in my ExpArticleController
?
Upvotes: 2
Views: 485
Reputation: 308
When using DI you are by definition relying on the interface. If you inject BaseArticleService then the only method available to you are the methods defined in this interface. In your case T getById(Long id);
Your way is not a bad way, you have a generic super class which allow you to initialise the interface with different parameters very easily, but you shouldn't expect to explicitely get any of the specific implementation. (maybe you could check and cast but it is not clean there).
As already stated you should extract the specific implementation in another class and directly inject this one in the controller requiring it. Keep your generic though, it is a nice way to to handle all the parametrized methods that will be shared between your controllers
Upvotes: 1