Google Guice依赖注入框架使用
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依赖注入框架使用相关推荐
- Google开源依赖注入框架-Guice指南
持续坚持原创输出,点击蓝字关注我吧 作者:软件质量保障 知乎:https://www.zhihu.com/people/iloverain1024 之前发过一篇文章<浅谈依赖注入的实现>, ...
- Google Guice 一个轻量级的依赖注入框架
1.美图 2.概述 2.1 背景 在做项目的时候,看见有段代码直接是使用Google Guice 注入了avaitor表达式. 2.1 官网 Github 主页:https://github.com/ ...
- guice依赖注入原理_Google Guice依赖注入示例教程
guice依赖注入原理 Google Guice is the framework to automate the dependency injection in applications. If y ...
- 依赖注入框架(DI Framework)
在采用依赖注入实现的 Notification 类中,虽然我们不需要用类似 hard code 的方式,在类内部通过 new 来创建 MessageSender 对象,但是,这个创建对象.组装(或注入 ...
- Android神匕首—Dagger2依赖注入框架详解
简介 Dagger-匕首,鼎鼎大名的Square公司旗下又一把利刃(没错!还有一把黄油刀,唤作ButterKnife) Dagger2 是一个Android依赖注入框架,由谷歌开发,最早的版本Dagg ...
- android组件浮动在activity上_Jetpack Hilt 依赖注入框架上手指南
code小生 一个专注大前端领域的技术平台公众号回复Android加入安卓技术群 作者:LvKang-insist 链接:https://juejin.im/post/5efdff9d6fb9a07e ...
- 依赖注入框架Autofac学习笔记
Autofac是一个轻量级的依赖注入框架,可以在这里面下载:http://code.google.com/p/autofac/downloads/list 要想了解什么是依赖注入,可以参考下这篇博客: ...
- 深入浅出依赖注入框架Dagger2
目录 目录 依赖注入 依赖注入实现的三种方式 1. 构造注入 2. 属性注入 3. 接口注入 Dagger2 Dagger2的引入 不带Module的Inject方式(Inject+Component ...
- 依赖注入框架 wire
在上一篇文章当中我们讲到了项目的目录结构,大体上水平切分为了四层,然后再根据需要进行垂直切分,然后由于我们大量的使用到了接口和依赖注入的手段,所以在项目初始化的时候如果手动进行依赖关系的初始化会比较麻 ...
- Android 依赖注入框架 Dagger2使用
前言 Dagger 2这个匕首确实很难上手,上手后又比较难瞬间掌握,可以这么说,刚开始使用就是用来尝(zhuang)鲜(X)的,但相信随着使用的加深,会不断体会到它对于整个项目架构的极强辅助作用,能使 ...
最新文章
- python密码测试代码_python使用正则表达式检测密码强度源码分享
- 后端返回number类型数据_【JavaScript 教程】标准库—Number 对象
- SpringMVC项目前台利用ajaxFileUpload传递图片后台接收
- linux文件 i节点结构,Linux 文件描述符 文件表项 i节点结构
- 杭电oj2072c语言,杭电acm 2072(单词数)
- WampServer详解
- linux python保存mp4
- 测试机的版本高于Xcode的版本的解决方法
- SeqGAN——对抗思想与增强学习的碰撞
- PHP buffer的机制
- 动手学无人驾驶(7):车道线检测
- LeetCode 1816. 截断句子
- 虚拟机安装Vmware-tools
- 三维地震数据segy数据显示
- H5py数据集的制作
- NOI2014起床困难综合症
- 阿里云(企业云解析DNS)让你的博客飞起来
- 人工智能、机器学习和模式识别以及神经网络
- elementUI表格合并单元格详解
- ada:世界上第一位程序员
热门文章
- 深圳Python培训:100天从新手到Python大师
- 提高项目39-电子词典
- Android学习笔记之MeasureSpec
- 重磅 | 完备的人工智能AI 学习——基础知识学习路线,所有资料免关注免套路直接网盘下载
- adventureworks mysql_AdventureWorks数据库的安装
- java 导出word简历_java导出生成word(类似简历导出)
- (无人驾驶仿真软件整理)
- 转:《欢聚时代(多玩YY)IPO招股书》(概要)
- mysql网吧管理系统_网吧管理系统(数据库)
- AndroidSDK和ADT下载地址