guice google_与Google Guice的动手实践
guice google
by Sankalp Bhatia
通过Sankalp Bhatia
与Google Guice的动手实践 (A hands-on session with Google Guice)
A few months ago, I wrote an article explaining dependency injection. I had mentioned of a follow-up article with a hands-on session of Google Guice. While I am disappointed in being so late in writing this, part of me is happy that I was able to write a second article.
几个月前,我写了一篇文章解释依赖注入。 我曾在Google Guice的动手实践中提到过后续文章。 尽管我对撰写本文这么晚感到失望,但我对能够撰写第二篇文章感到高兴。
This article assumes that you are familiar with what dependency injection is. I would recommend you to glance through my previous article as we will be building upon the examples we used there. If you are hearing the term for the first time, it will be worth it. If you are familiar with it, reading it won’t take much time :)
本文假定您熟悉什么是依赖项注入。 我建议您浏览上一篇文章,因为我们将在此使用的示例为基础。 如果您是第一次听到这个词,那将是值得的。 如果您熟悉它,阅读它不会花费很多时间:)
If you haven’t worked much with Guice, please check it out on GitHub here.
如果您与Guice的合作不多,请在GitHub 此处进行检查。
We will need to set up a few things before we start
开始之前,我们需要设置一些内容
JDK: We will be using Java for this task. So you will need to have a working JDK to be able to run Java code in your computer. To check if it’s already installed, run ‘java -version’ on the command line. If the version is 1.6 or greater, we are good. Just a note: I don’t think it would make much sense to attempt this if you don’t have experience with Java.
JDK :我们将使用Java来完成此任务。 因此,您将需要具有有效的JDK才能在计算机中运行Java代码。 要检查它是否已经安装,请在命令行上运行“ java -version”。 如果版本为1.6或更高,则表示我们很好。 请注意:如果您没有Java经验,那么尝试进行此操作没有多大意义。
Maven: We will be using maven as a build tool. To install maven, follow the instructions here https://maven.apache.org/install.html (Quite easy). To check if you already have maven, run ‘mvn -v’ on the command line.
Maven :我们将使用maven作为构建工具。 要安装maven,请按照https://maven.apache.org/install.html上的说明进行操作(非常简单)。 要检查您是否已经拥有Maven,请在命令行上运行“ mvn -v”。
git (optional): https://www.linode.com/docs/development/version-control/how-to-install-git-on-linux-mac-and-windows/
git (可选): https : //www.linode.com/docs/development/version-control/how-to-install-git-on-linux-mac-and-windows/
clone the hands on repository (FreshGuice): Run commands mentioned below
克隆动手操作存储库(FreshGuice) :运行下面提到的命令
cd folder/to/clone-into/ git clone https://github.com/sankalpbhatia/FreshGuice.git
绑定和绑定注释 (Bindings and Binding Annotations)
We are ready now. Let me start by introducing two crucial terms in the Guice framework: Bindings and Binding Annotations.
我们现在准备好了。 让我首先介绍Guice框架中的两个关键术语: 绑定和绑定注释。
Bindings: being the core concept of Guice, in literal terms, means an agreement or promise involving an obligation that cannot be broken. Now let’s map it in the context of Dependency Injection. When we make Guice bind an instance with a class, we make an agreement with Guice that “When I ask for an instance of X.java, give me this instance”. And this agreement can’t be broken.
装订:从字面上来讲,作为Guice的核心概念,是指涉及不可打破的义务的协议或承诺。 现在,在依赖注入的上下文中对其进行映射。 当我们使Guice 将一个类与一个实例绑定时 ,我们与Guice达成了一个协议,即“当我请求X.java的实例时,请给我这个实例”。 而且这个协议不能被打破。
Binding Annotations: Occasionally you’ll want multiple bindings for the same type. The annotation and (class) type together uniquely identify a binding. For example, in some cases, you might need two separate instances of the same class/ implementation of the same interface. To identify those, we use binding annotations. We will see some examples when we explain bindings.
绑定注释:有时,您需要同一个类型的多个绑定。 注释和(类)类型一起唯一地标识绑定。 例如,在某些情况下,您可能需要相同接口的相同类/实现的两个单独的实例。 为了识别这些,我们使用绑定注释。 当我们解释绑定时,我们将看到一些示例。
如何创建绑定 (How to create bindings)
The user guide section of Guice explains it perfectly. So I will just be copying it here:
Guice的用户指南部分对其进行了完美地解释。 所以我将在这里复制它:
To create bindings, extend
AbstractModule
and override itsconfigure
method. In the method body, callbind()
to specify each binding. These methods are type checked so the compiler can report errors if you use the wrong types. Once you've created your modules, pass them as arguments toGuice.createInjector()
to build an injector.要创建绑定,请扩展
AbstractModule
并覆盖其configure
方法。 在方法主体中,调用bind()
以指定每个绑定。 这些方法经过类型检查,因此如果使用错误的类型,则编译器可以报告错误。 创建模块后,请将其作为参数传递给Guice.createInjector()
以构建注入器。
There are a number of types of bindings: Linked, Instance, @Provides annotation, Provider bindings, Constructor bindings, and Un-targeted bindings.
绑定有多种类型:链接,实例,@ Provides批注,提供者绑定,构造函数绑定和非目标绑定。
For this article, I will only be covering Linked Bindings, Instance Bindings, @Provides annotation, and a special annotation @Inject. I very rarely use any other means to bind, but more information can be found at https://github.com/google/guice/wiki/Bindings.
对于本文,我将仅介绍链接绑定,实例绑定,@ Provides注释和特殊注释@Inject。 我很少使用其他任何方式进行绑定,但是可以在https://github.com/google/guice/wiki/Bindings中找到更多信息。
Linked Binding: a Linked binding maps a type/interface to its implementation. This example maps the interface MessageService to its implementation EmailService.
链接绑定:链接绑定将类型/接口映射到其实现。 本示例将接口MessageService映射到其实现EmailService。
In plain terms: When I ask Guice to give me an instance of MessageService, it will give me an instance of EmailService.
简而言之:当我要求Guice给我一个MessageService实例时,它将给我一个EmailService实例。
But, how will it know to create an instance of EmailService? We’ll see that later.
但是,如何知道创建EmailService的实例呢? 我们稍后会看到。
public class MessagingModule extends AbstractModule { @Override protected void configure() { bind(MessageService.class).to(EmailService.class); }}
Maybe we want more than one instance of MessageService in our project. At some places, we would want a SMSService to be associated with a MessageService, rather than an EmailService. In such cases, we use a binding annotation. To create a binding annotation, you will have to create two annotations like so:
也许我们的项目中需要多个MessageService实例。 在某些地方,我们希望将SMSService与MessageService关联,而不是与EmailService关联。 在这种情况下,我们使用绑定注释。 要创建绑定注释,您将必须创建两个注释,如下所示:
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)public @interface Email {}
@BindingAnnotation @Target({ FIELD, PARAMETER, METHOD }) @Retention(RUNTIME)public @interface SMS {}
You need not know about the metadata annotations (@Target, @ Retention). If interested, please read this: https://github.com/google/guice/wiki/BindingAnnotations
您不需要了解元数据注释(@ Target,@ Retention)。 如果有兴趣,请阅读以下内容: https : //github.com/google/guice/wiki/BindingAnnotations
Once we have the annotations with us, we can create two separate bindings which instruct Guice to create different instances of MessageService based on the BindingAnnotation (I think of it as a qualifier).
一旦有了注释,我们就可以创建两个单独的绑定,这些绑定指示Guice基于BindingAnnotation(我认为它是一个限定符)创建不同的MessageService实例。
public class MessagingModule extends AbstractModule { @Override protected void configure() { bind(MessageService.class).annotatedWith(Email.class) .to(EmailService.class);
bind(MessageService.class).annotatedWith(SMS.class) .to(SMSService.class); }}
2. Instance Binding: Binds a type to a specific instance
2. 实例绑定:将类型绑定到特定实例
bind(Integer.class) .annotatedWith(Names.named(“login timeout seconds”)) .toInstance(10);
One should avoid using .toInstance with objects that are complicated to create, since it can slow down application startup. You can use an @Provides method instead. In fact, you can even forget that we mentioned anything about Instance binding right now.
应该避免将.toInstance与创建起来很复杂的对象一起使用,因为它会减慢应用程序的启动速度。 您可以改用@Provides方法。 实际上,您甚至可以忘记我们现在提到的有关实例绑定的任何内容。
3. @ Provides annotation:
3. @提供注释 :
This is straight from Guice’s wiki, as it is fairly simple:
这直接来自Guice的Wiki,因为它非常简单:
When you need code to create an object, use an
@Provides
method. The method must be defined within a module, and it must have an@Provides
annotation. The method's return type is the bound type. Whenever the injector needs an instance of that type, it will invoke the method.需要代码创建对象时,请使用
@Provides
方法。 该方法必须在模块中定义,并且必须具有@Provides
批注。 该方法的返回类型是绑定类型。 只要注入器需要该类型的实例,它将调用该方法。
bind(MessageService.class)
.annotatedWith(Email.class)
.to(EmailService.class);
is same as
与...相同
@Provides@Emailpublic MessageService provideMessageService() { return new EmailService();}
where Email.java is a Binding annotation.
其中Email.java是Binding批注。
Dependencies can be passed to a method with this annotation which makes it extremely useful in real life projects. For example, for the code mentioned below, the injector will exercise the binding for the string parameter apiKey before invoking the method.
可以使用此批注将依赖项传递给方法,这使其在现实生活中的项目中极为有用。 例如,对于下面提到的代码,注入器将在调用方法之前对字符串参数apiKey进行绑定。
@Provides @PayPalCreditCardProcessor providePayPalCreditCardProcessor( @Named("PayPal API key") String apiKey) { PayPalCCProcessor processor = new PaypalCCProcessor(); processor.setApiKey(apiKey); return processor; }
4. @ Inject annotation (Just in Time binding): Whatever we covered up until now are called explicit bindings. If Guice, when trying to create an instance, does not find an explicit binding, it tries to create one using a Just-in-time binding.
4. @ Inject注释 (及时绑定):到目前为止,我们所涉及的内容都称为显式绑定。 如果Guice在尝试创建实例时未找到显式绑定,它将尝试使用即时绑定创建一个显式绑定。
Guice can create these bindings by using the class’s injectable constructor. This is either a non-private, no-arguments constructor or a constructor with the @Inject
annotation.
Guice可以使用类的可注入构造函数创建这些绑定。 这可以是非私有,无参数的构造函数,也可以是具有@Inject
批注的构造函数。
任务 (Task)
Now let’s move to the project we cloned from Github.
现在,我们转到从Github克隆的项目。
Like the examples in the previous article, this maven project implements a BillingService which charges a PizzaOrder using a credit card and generates a Receipt.
像上一篇文章中的示例一样,该maven项目实现了BillingService,该服务使用信用卡向PizzaOrder收费并生成回执。
The project structure is as follows:
项目结构如下:
Interfaces
介面
- BillingService — charges an order using a credit cardBillingService-使用信用卡对订单收费
- CreditCardProcessor — debits some amount from a credit cardCreditCardProcessor-从信用卡中扣款
- TransactionLog — logs resultsTransactionLog —记录结果
Classes
班级
src
src
- CreditCard — entity representing a Credit Card信用卡-代表信用卡的实体
- PizzaOrder — entity representing a Pizza orderPizzaOrder-代表比萨订单的实体
- Receipt — entity representing a receipt收据-代表收据的实体
- RealBillingService implements BillingServiceRealBillingService实现BillingService
- PaypalCreditCardProcessor implements CreditCardProcessorPaypalCreditCardProcessor实现CreditCardProcessor
- BankCreditCardProcessor implements CreditCardProcessorBankCreditCardProcessor实现CreditCardProcessor
- InMemoryTransactionLog implements TransactionLogInMemoryTransactionLog实现TransactionLog
- GuiceTest — Main class which uses BillingServiceGuiceTest —使用BillingService的主类
- BillingModule — All Guice bindings go hereBillingModule-所有Guice绑定都在这里
- GuiceInjectionTest : Unit tests to check binding constraintsGuiceInjectionTest:检查绑定约束的单元测试
The task here is to create Guice Bindings in the BillingModule such that the following constraints are satisfied:
此处的任务是在BillingModule中创建Guice绑定,以便满足以下约束:
- All implementations of BillingService should be bound to RealBillingService.BillingService的所有实现都应绑定到RealBillingService。
- CreditCardProcessor interface annotated with @Paypal should be bound to PaypalCreditCardProcessor class.用@Paypal注释的CreditCardProcessor接口应该绑定到PaypalCreditCardProcessor类。
- CreditCardProcessor interface named with string “Bank” should be bound to BankCreditCardProcessor class.以字符串“ Bank”命名的CreditCardProcessor接口应绑定到BankCreditCardProcessor类。
- BillingService instances returned by injector should have an instance of BankCreditCardProcessor as their dependency.注入程序返回的BillingService实例应具有BankCreditCardProcessor实例作为其依赖项。
- All implementations of TransactionLog should be bound to InMemoryTransactionLog.TransactionLog的所有实现都应绑定到InMemoryTransactionLog。
All five unit tests in GuiceInjectionTests should pass if the above conditions are satisfied. You should also be able to run the main method in GuiceTest.
如果满足上述条件,则GuiceInjectionTests中的所有五个单元测试都应通过。 您还应该能够在GuiceTest中运行main方法。
To test correctness:
要测试正确性:
- run unit tests运行单元测试
mvn test
This should run the test file GuiceInjectionTests.java.
这应该运行测试文件GuiceInjectionTests.java。
2. run the main file
2.运行主文件
mvn exec:java -Dexec.mainClass="GuiceTest"
This should execute the main class of the project, which does the end to end work of creating an order, processes payment using a credit card and generates a receipt.
这应该执行项目的主类,该主类负责创建订单的端到端工作,使用信用卡处理付款并生成收据。
You can comment if you have any questions and I will try answering them. Please note that there is no single correct answer for this exercise. DM me your solutions and I will add the answers to the repository. Or better still, send me a pull request :)
如果您有任何问题,可以发表评论,我会尽力回答。 请注意,此练习没有一个正确的答案。 DM给我您的解决方案,我将答案添加到资源库中。 或者更好,给我发送请求请求:)
翻译自: https://www.freecodecamp.org/news/a-hands-on-session-with-google-guice-5f25ce588774/
guice google
相关文章:

IQKeyboardManager使用方法
使用方法:将IQKeyboardManager 和 IQSegmentedNextPrevious类文件加进项目中。在AppDelegate文件中写下以下一行代码: [IQKeyBoardManager installKeyboardManager]; 搞定! 也可以开启或者关闭keyboard avoiding功能: [IQKeyBoard…

JQ加AJAX 加PHP实现网页登录功能
微信小程序开发交流qq群 173683895 承接微信小程序开发。扫码加微信。 前端代码 <!DOCTYPE HTML> <html><head><link href"css/style.css" rel"stylesheet" type"text/css" media"all" /><meta http-eq…

web安全简介_Web安全:HTTP简介
web安全简介by Alex Nadalin通过亚历克斯纳达林 Web安全:HTTP简介 (Web Security: an introduction to HTTP) This is part 2 of a series on web security: part 1 was “Understanding The Browser”这是有关网络安全的系列文章的第2部分:第1部分是“…

继承实现的原理、子类中调用父类的方法、封装
一、继承实现的原来 1、继承顺序 Python的类可以继承多个类。继承多个类的时候,其属性的寻找的方法有两种,分别是深度优先和广度优先。 如下的结构,新式类和经典类的属性查找顺序都一致。顺序为D--->A--->E--->B--->C。 class E:…

hdu 5366 简单递推
记f[i]为在长度是i的格子上面至少放一个木桩的方法数。考虑第i个格子,有放和不放两种情况。 1.如果第i个格子放了一个木桩,则i - 1和i - 2格子上面不能放木桩,方案数为:f[i - 3] 1 2.如果第i个格子没有放木桩,则方案数…

git 代理 git_如何不再害怕GIT
git 代理 git了解减少不确定性的机制 (Understanding the machinery to whittle away the uncertainty) 到底什么是Git? (What is Git anyway?) “It’s a version control system.”“这是一个版本控制系统。” 我为什么需要它? (Why do I need it?)…

Python 基础 - Day 2 Assignment - ShoppingCart 购物车程序
作业要求 1、启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 2、允许用户根据商品编号购买商品 3、用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒 4…

hdu 1878 欧拉回路
欧拉回路 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10548 Accepted Submission(s): 3849 Problem Description欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点…

bootstrap 时间日期日历控件(datetimepicker)附效果图
开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 效果图 代码 <!DOCTYPE html> <html><head><meta charset"UTF-8"><link href"https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" rel&q…

如何在您HTML中嵌入视频和音频
by Abhishek Jakhar通过阿比舍克贾卡(Abhishek Jakhar) 如何在您HTML中嵌入视频和音频 (How to embed video and audio in your HTML) HTML allows us to create standards-based video and audio players that don’t require the use of any plugins. Adding video and audi…

html 省份,城市 选择器附效果图
开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 效果图: 源码: <!DOCTYPE html> <html><head><meta charset"UTF-8"><link href"https://cdn.bootcss.com/bootstrap/3.3.7/css/boots…

机器学习:协方差矩阵
一、统计学的基本概念 统计学里最基本的概念就是样本的均值、方差、标准差。首先,我们给定一个含有n个样本的集合,下面给出这些概念的公式描述: 均值: 标准差: 方差: 均值描述的是样本集合的中间点…

TemplatedParent 与 TemplateBinding
http://blog.csdn.net/idebian/article/details/8761388转载于:https://www.cnblogs.com/changbaishan/p/4716414.html

避免成为垃圾邮件_如何避免犯垃圾
避免成为垃圾邮件by Yoel Zeldes由Yoel Zeldes 如何避免犯垃圾 (How to avoid committing junk) In the development process, every developer writes stuff they don’t intend to commit and push to the remote server, things like debug prints. It happens to all of u…

[bzoj2333] [SCOI2011]棘手的操作 (可并堆)
//以后为了凑字数还是把题面搬上来吧2333 发布时间果然各种应景。。。 Time Limit: 10 Sec Memory Limit: 128 MB Description 有N个节点,标号从1到N,这N个节点一开始相互不连通。第i个节点的初始权值为a[i],接下来有如下一些操作࿱…

vue.js created函数注意事项
因为created钩子函数是页面一加载完就会调用的函数,所以如果你想在这个组件拿值或者是赋值,很可能this里面能拿到数据,但是如果你用this.赋值的话,控制台或者debugger都会发现this里面有你所想要的数据,但是赋值后就是…

JS删除城市的后缀
开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 代码 const deleteStr str >{if (str.indexOf("市") ! -1 || str.indexOf("州") ! -1){str str.substring(0, str.length - 1)console.log(删除城市的最后一个字,str)return s…

gatsby_将您的GraphCMS数据导入Gatsby
gatsbyLets set up Gatsby to pull data from GraphCMS.让我们设置Gatsby来从GraphCMS中提取数据。 This will be a walk-through of setting up some basic data on the headless CMS, GraphCMS and then querying that data in Gatsby.这将是在无头CMS,GraphCMS上…

Java学习笔记07--日期操作类
一、Date类 在java.util包中定义了Date类,Date类本身使用非常简单,直接输出其实例化对象即可。 public class T { public static void main(String[] args) { Date date new Date(); System.out.println("当前日期:"date); //当前…

javascript数组集锦
设计数组的函数方法 toString, toLocaleString, valueOf, concat, splice, slice indexOf,lastIndexOf, push, pop, shift, unshift, sort, reverse map, reduce, reduceRight, filter, every, some, forEach 创建数组 数组字面量创建:var arr [val1, val2, val3];…

JS实现HTML标签转义及反转义
开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 编码反编码 function html_encode(str) { var s ""; if (str.length 0) return ""; s str.replace(/&/g, "&"); s s.replace(/</g, "<")…

喜欢把代码写一行的人_我最喜欢的代码行
喜欢把代码写一行的人Every developer has their favourite patterns, functions or bits of code. This is mine and I use it every day.每个开发人员都有自己喜欢的模式,功能或代码位。 这是我的,我每天都用。 它是什么? (What is it?) …

智能家居APP开发
智能家居APP开发 APP开发技术qq交流群:347072638 前言,随着智能硬件设备的流行,智能家居開始红火,智能家居就是家用电器的智能化。包含智能锁,灯,空调,灯,音箱等等,移动设…

android小技巧(二)
一、如何控制Android LED等?(设置NotificationManager的一些参数) 代码如下: final int ID_LED19871103; NotificationManager nm(NotificationManager)getSystemService(NOTIFICATION_SERVICE); Notification notification new Notification(); notificatio…

JS 验证表单不能为空
开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 JS 验证表单不能为空的简单demo,先看效果图 实现代码 <!--index.wxml--> <form classform bindsubmitformSubmit bindresetformReset><input namename value{{name}} placeho…

周末不用过来了,好好休息吧_如何好好休息
周末不用过来了,好好休息吧When I wrote about my productive routine in a previous article, I said I’d work for 1.5 hours and take a break for 30 minutes. And I’d repeat this sequence four times a day.当我在上一篇文章中谈到生产性例程时,…

HTML实现折现图完整源码及效果图
开发交流QQ群: 173683895 173683895 526474645 人满的请加其它群 效果图 源码 <!DOCTYPE html> <html><head><meta charset"utf-8" /><script src"https://cdnjs.cloudflare.com/ajax/libs/echarts/4.2.1/echarts-en.common…

Date类(java.util)和SimpleDateFormat类(java.text)
在程序开发中,经常需要处理日期和时间的相关数据,此时我们可以使用 java.util 包中的 Date 类。这个类最主要的作用就是获取当前时间,我们来看下 Date 类的使用: 使用 Date 类的默认无参构造方法创建出的对象就代表当前时间&#…

8月12笔记-安卓文件扫描
Android的文件系统 1.Android的项目是运行在Linux操作系统上的 2.Linux的文件系统根目录是/,Windows只有某个盘符根目录 3.mnt文件夹是手机的内存卡根目录,此目录是安卓开发经常使用的 4.在windows下,最高管理员叫做Administrator,…

可视化编码_Modulz简介:可视编码的下一步
可视化编码by Colm Tuite通过Colm Tuite Modulz简介:可视编码的下一步 (Introducing Modulz: The Next Step in Visual Coding) Modulz is a visual code editor for designing and building digital products — without writing code. Last week, we launched ou…