当前位置:网站首页>Google开源依赖注入框架-Guice指南
Google开源依赖注入框架-Guice指南
2022-06-28 09:41:00 【软件质量保障】
持续坚持原创输出,点击蓝字关注我吧
作者:软件质量保障
知乎:https://www.zhihu.com/people/iloverain1024
之前发过一篇文章《浅谈依赖注入的实现》,介绍了依赖注入的实现原理。文中提到高效实现依赖注入的工具Guice,本文就介绍一下这款Google开源的依赖注入框架Guice及其使用方法。
1. 简介
Google Guice 是一个轻量级的依赖注入框架,它支持Java 5或者更高版本的JDK,得利于Java 5中提供的泛型 (Generics) 和注解 (Annotations) ,它可以使得代码类型安全 (type-safe) 。那么何时使用在代码中使用 Guice 进行注入呢?一般来说,如果在你的应用代码中业务对象 (Business Objects) 之间的关系或者依赖需要维护的话,你就可以使用Guice 进行注入。
本文会通过一些例子来初步的认识一下 Guice 框架。
当然,不了解依赖注入基础知识的同学建议先看下这篇科普贴 《浅谈依赖注入的实现》。
2. 添加依赖
将以下依赖项添加到Maven项目中放入pom.xml中:
<dependency><groupId>com.google.inject</groupId><artifactId>guice</artifactId><version>4.1.0</version></dependency>
3. Guice的基础用法
3.1 项目样例代码
我还是用上篇文章中那个例子作为演示场景,即以现实生活中的三种通信方式为例:Email、SMS 和 IM。
首先,我们定义Communication类:
public class Communication {@Injectprivate Logger logger;@Injectprivate Communicator communicator;public Communication(Boolean keepRecords) {if (keepRecords) {System.out.println("Message logging enabled");}}public boolean sendMessage(String message) {return communicator.sendMessage(message);}}
这个Communication类是通信基类,此类的实例实现了通过可用的通信通道发送消息。如上代码所示,Communication会依赖Communicator,我们通过调用它来进行实际的消息传输。
Guice最基础的用法就是通过Injector对象实现,下面是客户端代码的例子:
public static void main(String[] args){Injector injector = Guice.createInjector();Communication comms = injector.getInstance(Communication.class)comms.sendMessage("软件质量保障");}
Guice 对依赖注入和管理采用代码优先的策略,因此我们可以不用处理很多令人抓狂的XML配置。
3.2. Guice bind
Binding is to Guice as wiring is to Spring。通过bind,我们可以实现Guice如何将依赖项注入到一个类中,
我们在com.google.inject.AbstractModule的实现中定义:
public class BasicModule extends AbstractModule {@Overrideprotected void configure() {bind(Communicator.class).to(DefaultCommunicatorImpl.class);}}
此模块实现将Communicator绑定到其默认实现类DefaultCommunicatorImpl上,在找到Communicator的地方都将注入Default CommunicatorImpl的实例。
3.3. @Named注解
我们可以使用 @Named注解来命名这些实体类,当你给它一个命名,它会返回一个命名好的 Annotation。例如在上面的例子中,可以使用 Names.named() 来完成相同的事情。
@Inject @Named("DefaultCommunicator")Communicator communicator;
@Overrideprotected void configure() {bind(Communicator.class).annotatedWith(Names.named("DefaultCommunicator")).to(DefaultCommunicatorImpl.class);}
使用@Named(“DefaultCommunicator”)注解将Communicator绑定到DefaultCommunicator实现类。
3.4. 构造函数绑定
我们还可以使用构造函数绑定注入一个没有默认无参数构造函数的依赖对象:
public class BasicModule extends AbstractModule {
@Override protected void configure() {
bind(Boolean.class).toInstance(true); bind(Communication.class).toConstructor( Communication.class.getConstructor(Boolean.TYPE));}构造函数绑定的另一种方法是实例绑定,我们直接为Communication.class绑定一个实例:
public class BasicModule extends AbstractModule {@Overrideprotected void configure() {bind(Communication.class).toInstance(new Communication(true));}}
无论我们在何处声明Communication类,此绑定都将提供Communication类的实例。但是在这种情况下,类的依赖关系树不会自动关联。
4. 依赖注入类型
Guice支持DI所推荐的标准注入类型。假设在Communicator类中,我们需要注入不同类型的CommunicationMode,可以通过下面几种方法实现。
4.1 属性注入
@Inject @Named("SMSComms")CommunicationMode smsComms;
我们可以使用@Named注解作为限定符来实现基于名称的定向注入。
4.2. Method注入
这里我们将使用一个setter方法来实现注入:
@Injectpublic void setEmailCommunicator(@Named("EmailComms") CommunicationMode emailComms) {this.emailComms = emailComms;}
4.3. 构造函数注入
我们还可以使用构造函数注入依赖:
@Injectpublic Communication(@Named("IMComms") CommunicationMode imComms) {this.imComms= imComms;}
4.4. 隐式注入
Guice 还提供隐式注入一些通用组件,例如Injector和java.util.Logger的实例等。大家是不是发现了,我们的所有示例都使用了Logger,但你是不是找不到它的实际绑定代码。
5. Guice Scope机制
Guice支持我们在其他DI框架中逐渐习惯的Scope和Scope机制。
5.1 单例
下面在我们的应用程序中注入一个单例,我们指定了Communicator的Scope,它将会被标志为一个单例实例。
bind(Communicator.class).annotatedWith(Names.named("AnotherCommunicator")).to(Communicator.class).in(Scopes.SINGLETON);
5.2. 饿汉式单例
下面注入一个饿汉式单例,asEagerSingleton()方法用来标记单例模式。
bind(Communicator.class).annotatedWith(Names.named("AnotherCommunicator")).to(Communicator.class).asEagerSingleton();
喜欢的话,就点个赞和在看再走吧
- END -
下方扫码关注 软件质量保障,与质量君一起学习成长、共同进步,做一个职场最贵Tester!
后台回复【测开】获取测试开发xmind脑图
后台回复【加群】获取加入测试社群!
往期推荐
边栏推荐
- Custom exception classes and exercises
- Dbeaver连接人大金仓KingbaseES V8(超详细图文教程)
- A classic JVM class loaded interview question class singleton{static singleton instance = new singleton(); private singleton() {}
- R语言plotly可视化:plotly可视化互相重叠的直方图(histogram)、在直方图的底部边缘使用geom_rug函数添加边缘轴须图Marginal rug plots
- Cisco * VRF(虚拟路由转发表)
- Key summary V of PMP examination - execution process group
- Crawler small operation
- Ingersoll Rand面板维修IR英格索兰微电脑控制器维修XE-145M
- Comprehensive evaluation of outline note taking software workflow: advantages, disadvantages and evaluation
- Matplotlib attribute and annotation
猜你喜欢

Looking at jBPM from jbm3 to jbm5 and activiti

PyGame game: "Changsha version" millionaire started, dare you ask? (multiple game source codes attached)

适配器模式(Adapter)

再见!IE浏览器,这条路由Edge替IE继续走下去

全链路业务追踪落地实践方案

Unity AssetBundle asset packaging and asset loading

This article explains in detail the difficult problems and solutions faced by 3D cameras

Huawei OSPF single region

DolphinScheduler使用系统时间
![[ybtoj advanced training guidance] class roll call [string hash]](/img/5b/bbf8fa51d180b50fbbee4bcc278c70.jpg)
[ybtoj advanced training guidance] class roll call [string hash]
随机推荐
Instant messaging and BS architecture simulation of TCP practical cases
This article explains in detail the difficult problems and solutions faced by 3D cameras
mysql打不开,闪退
What is the difference between MySQL development environment and test environment??
[ybtoj advanced training guidance] class roll call [string hash]
通过PyTorch构建的LeNet-5网络对手写数字进行训练和识别
TCP实战案例之即时通信、BS架构模拟
第五章 树和二叉树
==And eqauls()
装饰模式(Decorator)
abnormal
Thread lifecycle
Stutter participle_ Principle of word breaker
ffmpeg录音录像
Matplotlib属性及注解
flink cep 跳过策略 AfterMatchSkipStrategy.skipPastLastEvent() 匹配过的不再匹配 碧坑指南
Custom exception classes and exercises
第三章 栈和队列
How to view the web password saved by Google browser
优秀笔记软件盘点:好看且强大的可视化笔记软件、知识图谱工具Heptabase、氢图、Walling、Reflect、InfraNodus、TiddlyWiki