添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

在开发中我们会经常看到,一个接口被多个实现类继承。那么我们实际开发中如何解决,分配路由多个实现类的、

首先说一下用到的技术也很简单。那就是spring的。ApplicationContext类、里面的getBeanofType();

直接代码:

首先定义一个个性接口

* 个性化定制服务接口 * @author david public interface CustomPageTemplate extends PageTemplate { * 服务实现的优先级,数字越小越优先 public int priority(); * 服务实现能够处理的任务 public boolean accept(CrawlTask task);
public interface PageTemplate {
/**
* 根据任务数据获取展示层模型
*/
Page getPageModel(CrawlTask task);
}
然后我们定义一个路由类,由这个类。选择不同的实现

@Component
public class PageTemplateRouter {
    @Autowired
    private ApplicationContext applicationContext;  
    private List<CustomPageTemplate> templates;
    public PageTemplateRouter() {
        // TODO Auto-generated constructor stub
    @PostConstruct
    public void init(){
        Map<String, CustomPageTemplate> beans = applicationContext.getBeansOfType(CustomPageTemplate.class);
        templates = beans.values().stream()
           .sorted((a,b)->a.priority()-b.priority())
           .collect(Collectors.toList());
     * 根据任务情况判断应该选择具体的PageTemplate实现类
     * @param task
     * @return
    public PageTemplate getPageTemplate(CrawlTask task){
        return templates.stream().filter(t->t.accept(task)).findFirst().get();

简单明了,一下,实现。但是这个可不是自动识别,下面我们就写一个,自动识别的

1.如何获取应用上下文对象,applicationcontext

任何类,实现 applicationContextAware接口,实现setApplicationContext方法,就会在启动时,向实现类的实现方法注入applicationcontext对象

@Component
public class TestServiceFactory implements ApplicationContextAware {
    private static Map<TypeEnum, TestService> testServiceMap;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String,TestService> map = applicationContext.getBeansOfType(TestService.class);
        testServiceMap = new HashMap<>();
        map.forEach((key,value) -> testServiceMap.put(value.getCode(),value));
    public TestService getTestService(TypeEnum typeEnum) {
        return testServiceMap.get(typeEnum);

2. 怎么根据外部条件实现获得对应的实现类?

可以在接口中加一个getCode方法,实现类实现这个方法,然后返回一个定义的枚举类型,然后将getBeansOfType获得map进行转换

枚举:

package com.util;
public enum TypeEnum { html, template
接口:

package com.service; import com.util.TypeEnum; import org.springframework.stereotype.Service; @Service
public interface TestService { public TypeEnum getCode(); public String test();

定义实现类:

@Service
public class TestServiceHtml implements TestService {
    @Override
    public TypeEnum getCode() {
        return TypeEnum.html;
    @Override
    public String test() {
        return this.toString();
@Service
public class TestServiceTemplate implements TestService {
    @Override
    public TypeEnum getCode() {
        return TypeEnum.template;
    @Override
    public String test() {
        return this.toString();

controller类:

@Controller
@RequestMapping("test")
public class TestController {
    @Autowired
    TestServiceFactory testServiceFactory;
    private TestService testService;
    @ResponseBody
    @RequestMapping("test")
        public String test(HttpServletRequest request, HttpServletResponse response){
        String type = request.getParameter("type");
        testService = getTestService(type);
        return testService.test();
    public TestService getTestService(String type) {
        TypeEnum typeEnum = null;
        if(type.equals("1")) typeEnum = TypeEnum.html;
        if(type.equals("2")) typeEnum = TypeEnum.template;
        return testServiceFactory.getTestService(typeEnum);

以上两种模式都可以完成,多个实现类的自动分配。

这是其中一种,还有一种,一个接口,多个实现类。我们可以利用。applicationContext.getBean();这种实现方式。这也是spring获取实现类的方法。

applicationContext.getBean(task.identifier()+"/Provider", ProviderSao.class);

这样我们也可以根据,实现类上的id或者name名称去找对应的接口实现。,然后用接口返回接收。