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

  • 相关阅读:
    51 Nod 1086 多重背包问题(单调队列优化)
    51 Nod 1086 多重背包问题(二进制优化)
    51 Nod 1085 01背包问题
    poj 2559 Largest Rectangle(单调栈)
    51 Nod 1089 最长回文子串(Manacher算法)
    51 Nod N的阶乘的长度 (斯特林近似)
    51 Nod 1134 最长递增子序列(经典问题回顾)
    51 Nod 1020 逆序排列
    PCA-主成分分析(Principal components analysis)
    Python中cPickle
  • 原文地址:https://www.cnblogs.com/bigdataer/p/6961685.html
Copyright © 2011-2022 走看看