Google Guice是一个轻量级依赖注入框架,和Spring类似。下面结合一些示例来讲解其使用方式。

首先引入maven依赖:

<dependency><groupId>com.google.inject</groupId><artifactId>guice</artifactId><version>4.1.0</version>
</dependency>

示例1:

package com.jingchenyong.boundless.guice.example2;import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;@Singleton
class HelloPrinter {public void print() {System.out.println("Hello, World!");}
}@Singleton
public class Sample {@Injectprivate HelloPrinter printer;public void hello() {printer.print();}public static void main(String[] args) {Injector injector = Guice.createInjector();Sample sample1 = injector.getInstance(Sample.class);sample1.hello();}
}

Guice最常用的两个注解就是@Singleton和@Inject,前者表示构建的对象是单例的,后者表示被标注的字段将使用Guice自动注入。示例1中使用Guice创建了一个注射器injector,Guice会自动装配依赖树,然后通过getInstance()方法获取指定的类实例并运行。

如果不使用Singleton标注类,那么每次获取实例时,Guice会重新构造一个,增加性能损耗。如下示例2所示,在Sample类上取消了Singleton注解,那么每次injector.getInstance(Sample.class)调用获取的都是不同的实例(对象堆地址不同)。

示例2:

package com.jingchenyong.boundless.guice.example2;import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;@Singleton
class HelloPrinter {public void print() {System.out.println("Hello, World!");}
}public class Sample {@Injectprivate HelloPrinter printer;public void hello() {printer.print();}public static void main(String[] args) {Injector injector = Guice.createInjector();Sample sample1 = injector.getInstance(Sample.class);System.out.println(sample1);Sample sample2 = injector.getInstance(Sample.class);System.out.println(sample2);}
}
// 运行结果:
com.jingchenyong.boundless.guice.example2.Sample@74650e52
com.jingchenyong.boundless.guice.example2.Sample@15d0c81b

当一个接口有多个实现时,可以通过@ImplementedBy注解指定接口的具体实现类(不太优雅)。

示例3:

package com.jingchenyong.boundless.guice.example3;import com.google.inject.Guice;
import com.google.inject.ImplementedBy;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;@ImplementedBy(ComplexHelloPrinter.class)
interface IHelloPrinter {void print();
}@Singleton
class SimpleHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Simple World");}
}@Singleton
class ComplexHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Complex World");}}@Singleton
public class Sample {@Injectprivate IHelloPrinter printer;public void hello() {printer.print();}public static void main(String[] args) {Injector injector = Guice.createInjector();Sample sample = injector.getInstance(Sample.class);sample.hello();}
}// 运行结果
Hello, Complex World

为了解决在接口类上添加@ImplementedBy注解不优雅的方式,可以使用Guice Module定义装配规则,它相当于Spring的XML文件,只不过它的装配规则都是使用代码定义的。如下示例4所示:

示例4:

package com.jingchenyong.boundless.guice.example4;import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;interface IHelloPrinter {void print();
}@Singleton
class SimpleHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Simple World");}
}@Singleton
class ComplexHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Complex World");}
}class SampleModule extends AbstractModule {@Overrideprotected void configure() {bind(IHelloPrinter.class).to(SimpleHelloPrinter.class);}}public class Sample {@Injectprivate IHelloPrinter printer;public void hello() {printer.print();}public static void main(String[] args) {Injector injector = Guice.createInjector(new SampleModule());Sample sample = injector.getInstance(Sample.class);sample.hello();}
}

我们也可以使用@Named来指定依赖注入的实现(两种方式:字段注入和构造注入)

字段注入:

package com.jingchenyong.boundless.guice.example5;import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.name.Names;interface IHelloPrinter {void print();
}@Singleton
class SimpleHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Simple World");}
}@Singleton
class ComplexHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Complex World");}
}class SampleModule extends AbstractModule {@Overrideprotected void configure() {bind(IHelloPrinter.class).annotatedWith(Names.named("simple")).to(SimpleHelloPrinter.class);bind(IHelloPrinter.class).annotatedWith(Names.named("complex")).to(ComplexHelloPrinter.class);}}public class Sample {@Inject@Named("simple")private IHelloPrinter simplePrinter;@Inject@Named("complex")private IHelloPrinter complexPrinter;public void hello() {simplePrinter.print();complexPrinter.print();}public static void main(String[] args) {Injector injector = Guice.createInjector(new SampleModule());Sample sample = injector.getInstance(Sample.class);sample.hello();}
}

构造注入:

package com.jingchenyong.boundless.guice.example5;import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.name.Named;
import com.google.inject.name.Names;interface IHelloPrinter {void print();
}@Singleton
class SimpleHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Simple World");}
}@Singleton
class ComplexHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Complex World");}
}class SampleModule extends AbstractModule {@Overrideprotected void configure() {bind(IHelloPrinter.class).annotatedWith(Names.named("simple")).to(SimpleHelloPrinter.class);bind(IHelloPrinter.class).annotatedWith(Names.named("complex")).to(ComplexHelloPrinter.class);}}public class Sample {@Named("simple")private IHelloPrinter simplePrinter;@Named("complex")private IHelloPrinter complexPrinter;@Injectpublic Sample(@Named("simple") IHelloPrinter simplePrinter, @Named("complex") IHelloPrinter complexPrinter) {this.simplePrinter = simplePrinter;this.complexPrinter = complexPrinter;}public void hello() {simplePrinter.print();complexPrinter.print();}public static void main(String[] args) {Injector injector = Guice.createInjector(new SampleModule());Sample sample = injector.getInstance(Sample.class);sample.hello();}
}

有时候需要直接注入一个对象实例,而不是从依赖关系中解析。如果我们注入基本类型可以在SampleModule的configure()方法中添加如下语句:

bind(String.class).annotatedWith(Names.named("url")).toInstance("http://www.baidu.com");

那么在Sample中就可以添加如下语句进行自动装配:

@Named("url")
private String url;

当一个对象很复杂,无法使用简单的构造器来生成的时候,我们就可以使用使用实现Provider接口的类来生成复杂对象,然后在SampleModule的configure()方法中配置该复杂对象

(1)使用实现Provider接口的类来生成复杂对象

class LogParam {@Overridepublic String toString() {return "我是test";}
}
// Log类为Sample类需要加载的复杂对象的抽象类(说它复杂因为包含了LogParam的实例)
abstract class Log {protected LogParam test;public abstract void setTest(LogParam test);public abstract LogParam getTest();
}// Log的实现类
class MyLog extends Log {@Overridepublic void setTest(LogParam test) {this.test = test;}@Overridepublic LogParam getTest() {return this.test;}}class LogProvider implements Provider<Log> {private final LogParam test;// 这里会自动装配LogParam实例,也可在get方法中自定义构造该实例@Injectpublic LogProvider(LogParam test) {this.test = test;}@Overridepublic Log get() {MyLog myLog = new MyLog();myLog.setTest(test);return myLog;}}

(2)在SampleModule的configure()方法中配置该复杂对象

bind(Log.class).toProvider(LogProvider.class);

(3)Sample类中装配使用Log实现类

@Named("simple")
private IHelloPrinter simplePrinter;@Named("complex")
private IHelloPrinter complexPrinter;private Log log;@Inject
public Sample(@Named("simple") IHelloPrinter simplePrinter, @Named("complex") IHelloPrinter complexPrinter, Log log) {this.simplePrinter = simplePrinter;this.complexPrinter = complexPrinter;this.log = log;
}

Guice还可以自动注入Set,Map容器,添加扩展库依赖

<dependency><groupId>com.google.inject.extensions</groupId><artifactId>guice-multibindings</artifactId><version>4.1.0</version>
</dependency>

注入Set

package com.jingchenyong.boundless.guice.example6;import java.util.Set;import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.multibindings.Multibinder;interface IHelloPrinter {void print();
}@Singleton
class SimpleHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Simple World");}
}@Singleton
class ComplexHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Complex World");}
}class SampleModule extends AbstractModule {@Overrideprotected void configure() {Multibinder<IHelloPrinter> printers = Multibinder.newSetBinder(binder(), IHelloPrinter.class);printers.addBinding().to(SimpleHelloPrinter.class);printers.addBinding().to(ComplexHelloPrinter.class);}}public class Sample {@Injectprivate Set<IHelloPrinter> printers;public void hello() {for (IHelloPrinter printer : printers) {printer.print();}}public static void main(String[] args) {Injector injector = Guice.createInjector(new SampleModule());Sample sample = injector.getInstance(Sample.class);sample.hello();}
}
// 运行结果
Hello, Simple World
Hello, Complex World

注入Map

package com.jingchenyong.boundless.guice.example6;import java.util.Map;import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Singleton;
import com.google.inject.multibindings.MapBinder;interface IHelloPrinter {void print();
}@Singleton
class SimpleHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Simple World");}
}@Singleton
class ComplexHelloPrinter implements IHelloPrinter {@Overridepublic void print() {System.out.println("Hello, Complex World");}
}class SampleModule extends AbstractModule {@Overrideprotected void configure() {MapBinder<String, IHelloPrinter> printers = MapBinder.newMapBinder(binder(), String.class, IHelloPrinter.class);printers.addBinding("simple").to(SimpleHelloPrinter.class);printers.addBinding("complex").to(ComplexHelloPrinter.class);}}public class Sample {@Injectprivate Map<String, IHelloPrinter> printers;public void hello() {for (String name : printers.keySet()) {printers.get(name).print();}}public static void main(String[] args) {Injector injector = Guice.createInjector(new SampleModule());Sample sample = injector.getInstance(Sample.class);sample.hello();}
}
//运行结果
Hello, Simple World
Hello, Complex World

Google Guice依赖注入框架使用相关推荐

  1. Google开源依赖注入框架-Guice指南

    持续坚持原创输出,点击蓝字关注我吧 作者:软件质量保障 知乎:https://www.zhihu.com/people/iloverain1024 之前发过一篇文章<浅谈依赖注入的实现>, ...

  2. Google Guice 一个轻量级的依赖注入框架

    1.美图 2.概述 2.1 背景 在做项目的时候,看见有段代码直接是使用Google Guice 注入了avaitor表达式. 2.1 官网 Github 主页:https://github.com/ ...

  3. guice依赖注入原理_Google Guice依赖注入示例教程

    guice依赖注入原理 Google Guice is the framework to automate the dependency injection in applications. If y ...

  4. 依赖注入框架(DI Framework)

    在采用依赖注入实现的 Notification 类中,虽然我们不需要用类似 hard code 的方式,在类内部通过 new 来创建 MessageSender 对象,但是,这个创建对象.组装(或注入 ...

  5. Android神匕首—Dagger2依赖注入框架详解

    简介 Dagger-匕首,鼎鼎大名的Square公司旗下又一把利刃(没错!还有一把黄油刀,唤作ButterKnife) Dagger2 是一个Android依赖注入框架,由谷歌开发,最早的版本Dagg ...

  6. android组件浮动在activity上_Jetpack Hilt 依赖注入框架上手指南

    code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 作者:LvKang-insist 链接:https://juejin.im/post/5efdff9d6fb9a07e ...

  7. 依赖注入框架Autofac学习笔记

    Autofac是一个轻量级的依赖注入框架,可以在这里面下载:http://code.google.com/p/autofac/downloads/list 要想了解什么是依赖注入,可以参考下这篇博客: ...

  8. 深入浅出依赖注入框架Dagger2

    目录 目录 依赖注入 依赖注入实现的三种方式 1. 构造注入 2. 属性注入 3. 接口注入 Dagger2 Dagger2的引入 不带Module的Inject方式(Inject+Component ...

  9. 依赖注入框架 wire

    在上一篇文章当中我们讲到了项目的目录结构,大体上水平切分为了四层,然后再根据需要进行垂直切分,然后由于我们大量的使用到了接口和依赖注入的手段,所以在项目初始化的时候如果手动进行依赖关系的初始化会比较麻 ...

  10. Android 依赖注入框架 Dagger2使用

    前言 Dagger 2这个匕首确实很难上手,上手后又比较难瞬间掌握,可以这么说,刚开始使用就是用来尝(zhuang)鲜(X)的,但相信随着使用的加深,会不断体会到它对于整个项目架构的极强辅助作用,能使 ...

最新文章

  1. python密码测试代码_python使用正则表达式检测密码强度源码分享
  2. 后端返回number类型数据_【JavaScript 教程】标准库—Number 对象
  3. SpringMVC项目前台利用ajaxFileUpload传递图片后台接收
  4. linux文件 i节点结构,Linux 文件描述符 文件表项 i节点结构
  5. 杭电oj2072c语言,杭电acm 2072(单词数)
  6. WampServer详解
  7. linux python保存mp4
  8. 测试机的版本高于Xcode的版本的解决方法
  9. SeqGAN——对抗思想与增强学习的碰撞
  10. PHP buffer的机制
  11. 动手学无人驾驶(7):车道线检测
  12. LeetCode 1816. 截断句子
  13. 虚拟机安装Vmware-tools
  14. 三维地震数据segy数据显示
  15. H5py数据集的制作
  16. NOI2014起床困难综合症
  17. 阿里云(企业云解析DNS)让你的博客飞起来
  18. 人工智能、机器学习和模式识别以及神经网络
  19. elementUI表格合并单元格详解
  20. ada:世界上第一位程序员

热门文章

  1. 深圳Python培训:100天从新手到Python大师
  2. 提高项目39-电子词典
  3. Android学习笔记之MeasureSpec
  4. 重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载
  5. adventureworks mysql_AdventureWorks数据库的安装
  6. java 导出word简历_java导出生成word(类似简历导出)
  7. (无人驾驶仿真软件整理)
  8. 转:《欢聚时代(多玩YY)IPO招股书》(概要)
  9. mysql网吧管理系统_网吧管理系统(数据库)
  10. AndroidSDK和ADT下载地址