版权申明:转载请注明出处。
文章来源: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

使用@Named注解绑定多个实现(java,scala)的更多相关文章

  1. java 编程基础:【注解】 提取注解信息,利用自定义注解编写测试类,注解绑定事件

    提取注解信息 使用注解修饰了类.方法.成员变量等成员之后,这些注解不会自己生效,必须由开发者提供相应工具来提取并处理注解信息.   Java使用java.lang.annotation.Annotat ...

  2. 注解的基本盘点 -- 《Java编程思想》

    注解(元数据)为我们在代码中添加信息提供了一种形式化的方法,使我们可以在之后的某一个时刻非常方便地使用这些数据. ---<Java编程思想> 其实注解可以理解为一个工具类,只要使用了这个工 ...

  3. docker 通过commit方法创建镜像(Tomcat+Java+Scala)

    前一阵试了试写Dockerfile创建docker image,但有时全靠Dockerfile写实在有些难度,退而求其次试一试使用commit来创建镜像: 想了想干脆创建一个Java+Scala+To ...

  4. Akka.NET是Java/Scala 流行框架Akka的一个 .NET 开源移植

    Akka.NET v1.0 已发布,支持Mono Akka.NET 是Java/Scala 流行框架Akka的一个 .NET 开源移植.可用于构建高并发,分布式和容错事件驱动的应用在 .NET 和 M ...

  5. 今天又犯了Java/Scala里面substring的错误

    每次都误以为是 substring(startIndex, length) 其实是 substring(startIndex, endIndex) 嗯 Java/Scala 跟 C++ 是不一样的.

  6. 在IntelliJ IDEA中创建和运行java/scala/spark程序

    本文将分两部分来介绍如何在IntelliJ IDEA中运行Java/Scala/Spark程序: 基本概念介绍 在IntelliJ IDEA中创建和运行java/scala/spark程序 基本概念介 ...

  7. Spring AOP注解为什么失效?90%Java程序员不知道

    使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方加,不然不会生效. 如下面几种场景 1.Controller直接调用Se ...

  8. Spring课程 Spring入门篇 4-6 Spring bean装配之基于java的容器注解说明--@ImportResource和@Value java与properties文件交互

    1 解析 1.1 这两个注解应用在什么地方 1.2 应用方式 1.3 xml方式实现取值 2 代码演练 2.1 @ImportResource和@Value代码演练 1 解析 1.1 这两个注解应用在 ...

  9. Java Scala获取所有注解的类信息

    要想获取使用指定注解的类信息,可借助工具: org.reflections.Reflections 此工具将Java反射进行了高级封装,Reflections 通过扫描 classpath,索引元数据 ...

随机推荐

  1. FW:主流RPC框架

    主流RPC框架  2015年10月27日  zman  RPC 介绍目前在互联网公司比较流行的开源的RPC框架. RPC框架比较   语言 协议 ​服务治理 ​社区 机构 Hessian 多语言 he ...

  2. 前端开发 - HTML - 简介

    一.web1.0时代的网页制作 静态网页,所谓的静态网页就是没有与用户进行交互而仅仅供读者浏览的网页,我们当时称为"牛皮癣"网页.例如一篇QQ日志.一篇博文等展示性文章. 网页三剑 ...

  3. Java8 新特性之Lambda表达式

    1. Lambda 表达式概述 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递); Lambda 表达式可以写出更简洁,更灵活的代码 ...

  4. Python面向对象高级

    一  反射 反射也可以说是python的自省机制 反射就是通过字符串的形式,导入模块,然后以字符串的形式去查找指定函数并执行.利用字符串的形式去模块(对象)中操作(查找/获取/添加/删除)属性,是一种 ...

  5. python web中的文件上传与下载

    django 框架下 实现服务端的文件上传与下载: import jsonimport osimport uuid def attachment_upload(request): "&quo ...

  6. APICloud常用方式

    新打开一个窗口: api.openWin({ name: 'unlogin', url: 'widget://html/unlogin.html', pageParam: { } }); 新打开一个F ...

  7. css3 利用dispaly:flex

    直接上代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  8. (转)VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径说明

      $(RemoteMachine) 设置为“调试”属性页上“远程计算机”属性的值.有关更多信息,请参见更改用于 C/C++ 调试配置的项目设置. $(References) 以分号分隔的引用列表被添 ...

  9. IOS自动化定位方式

    原文地址http://blog.csdn.net/wuyepiaoxue789/article/details/77885136 元素属性的介绍 type:元素类型,与className作用一致,如: ...

  10. DEPHI XE5 XE6 ANDROID IOS开发的几点体会

    DEPHI XE5 XE6 ANDROID IOS开发的几点体会 2014-09-04 20:48 1.不纠结于APK或者APP的大小.现在的客户端设备都很廉价,300元以上的新安卓设备都不在乎软件的 ...