zoukankan      html  css  js  c++  java
  • 使用@Named注解绑定多个实现(java,scala)

    版权申明:转载请注明出处。
    文章来源:http://bigdataer.net/?p=330

    排版乱?请移步原文获得更好的阅读体验

    1.背景

    最近项目中使用了guice作为依赖注入的框架。碰到一个如下的场景:
    定义了一个从不同渠道输入数据的接口AbstractImporter,设计之初的目标是抽象从hdfs,kafka,DBMS等数据源输入数据处理。那么对应的实现就会有HdfsImporter,KafkaImporter,即一个接口对应多个实现。google官方的文档提供了两种实现方法:1.给每一个绑定对应写一个自定义注解,2.使用@Named注解。第二个方法的好处是不用为每个绑定写一个自定义注解,类似于spring中的@Resource,于是果断采用第二种方式,但是google文档上关于如何实现写的不是很详细,而且好多文章中给的都是类似下面的错误实现:

    java    13行

    public class PlayerModule implements Module{
       public void configure(Binder binder) {
           binder.bind(Player.class).annotatedWith(Names.named("Good")).to(
               GoodPlayer.class);
           binder.bind(Player.class).annotatedWith(Names.named("Bad")).to(
           BadPlayer.class);        
       }
    }
    
    //现在在客户端代码中,我们将使用 @Named() annotation来获取注释。
    @Named("Good") Player goodPlayer = (Player)injector.getInstance(Player.class);
    @Named("Bad") Player badPlayer = (Player)injector.getInstance(Player.class);
    

    一跑就会报“接口没有绑定实现类”的错误,非常的蛋疼!

    2.总结

    后来受guice文档上简短代码片段的启发加上自己的领悟,终于解决了这个问题。回头想想导致整个问题的原因是自己盲目相信网上的文章且对guice作为一个依赖注入框架的认识不深导致的。下面贴出能正确运行的代码:

    java    6行

    //接口
    package net.bigdataer.demo.juice;
    public interface People {
        public void setId(int id);
    }
    

    java    9行

    package net.bigdataer.demo.juice;
    //实现类
    public class Student implements People {
        public void setId(int id) {
    
            System.out.println(id);
        }
    }
    

    java    8行

    package net.bigdataer.demo.juice;
    //实现类
    public class Teacher implements People {
        public void setId(int id) {
            System.out.println(id);
        }
    }
    

    java    13行

    package net.bigdataer.demo.juice;
    
    import com.google.inject.Binder;
    import com.google.inject.Module;
    import com.google.inject.name.Names;
    //module类,绑定实现类到接口
    public class JuiceModule implements Module {
        public void configure(Binder binder) {
            binder.bind(People.class).annotatedWith(Names.named("Teacher")).to(Teacher.class);
            binder.bind(People.class).annotatedWith(Names.named("Student")).to(Student.class);
        }
    }
    

    重要的代码段,如何使用@Named绑定多个实现

    java    29行

    package net.bigdataer.demo.juice;
    
    import com.google.inject.Inject;
    import com.google.inject.name.Named;
    
    public class InjectionConfig {
    
        private People student;
        private People teacher;
    
        public People getStudent() {
            return student;
        }
    
        @Inject
        public void setStudent(@Named("Student") People student) {
            this.student = student;
        }
    
        public People getTeacher() {
            return teacher;
        }
    
        @Inject
        public void setTeacher(@Named("Teacher") People teacher) {
            this.teacher = teacher;
        }
    }
    

    java    18行

    package net.bigdataer.demo.juice;
    
    import com.google.inject.Guice;
    import com.google.inject.Injector;
    
    public class NameMain {
    
        public static void main(String[] args){
           Injector injector = Guice.createInjector(new JuiceModule());
            InjectionConfig config = injector.getInstance(InjectionConfig.class);
            People teacher = config.getTeacher();
            teacher.setId(2);
    
            People student = config.getStudent();
            student.setId(23);
        }
    }
    

    3.升华

    因为guice框架是用在我的项目中的,而整个项目是用scala语言写的,所以我也测试了guice在scala中的使用。总体感觉就是配合scala的语法,用起来非常爽。贴一下对应java中InjectionConfig类的scala实现:

    scala    21行

    package net.bigdataer.demo.juice
    
    import com.google.inject.Inject
    import com.google.inject.name.Named
    
    class SInjectionConfig {
    
      //使用named注解绑定多个实现
      @Inject
      @Named("Teacher")
       var teacher:SPeople = _
    
      @Inject
      @Named("Student")
       var student:SPeople = _
    
      //普通绑定,绑定一个实现
      @Inject
      var log:Log = _
    }
    

    代码量不是一般的少。完整的demo放在了github上,地址:https://github.com/bigdataer01/scala-guice-demo

    更多文章请关注微信公众号:bigdataer

  • 相关阅读:
    利用web.confing保存数据
    sql2005 未知错误 MS Visual Database Tools
    安装SQL2005时系统配置检查出现“性能监视器计数器要求”
    DNN中的Unit Test
    介绍一个收费的SVN Host
    DNN Navisuite菜单模块原始XML文件的格式
    如何使用C#调用Java
    介绍几个DNN SEO模块,可免费试用的
    帮你找到色彩Photoshop LAB Color
    Google PR 到4了
  • 原文地址:https://www.cnblogs.com/bigdataer/p/6961685.html
Copyright © 2011-2022 走看看