Guice 4.1教程

Guice是Google开发的一个开源轻量级的依赖注入框架,运行速度快,使用简单。

项目地址:https://github.com/google/guice/

最新的版本是4.1,本文基于此版本。

0. 什么是依赖注入?

依赖注入(Dependency Injection)是一种思想。

在一般的编程中,如果我们想要使用一个class的实例,那么必须要调用构造方法new class()手动将其实例化,如果这个class中又有对其他class属性的引用,那么在构造方法中,又要调用其他class的构造方法将其实例化。

这就是“依赖”。

Guice这种依赖注入框架的作用就是接管class之间的依赖关系,如果我们想要使用一个class的实例,Guice会自动生成实现类的实例并交给我们。

这个过程就叫做“注入”。

1. 利用Module的依赖注入

//定义Dog接口
public interface Dog {
    void bark();
}

//定义BlackDog实现类
public class BlackDog implements Dog{
    @Override
    public void bark() {
        System.out.println("i am black dog");
    }
}

//依赖注入
public class GuiceTest {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new Module() {
            @Override
            public void configure(Binder binder) {
                binder.bind(Dog.class).to(BlackDog.class);
            }
        });
        Dog dog = injector.getInstance(Dog.class);
        dog.bark();
    }
}

输出结果如下

i am black dog

这个例子非常简单,先在自定义的Module中将Dog接口与BlackDog实现类关联起来。此时如果调用getInstance方法想要获取Dog接口的实例,就自动创建一个BlackDog的实例并返回。

2. 绑定到实例的依赖注入

public static void main(String[] args) {
        Injector injector = Guice.createInjector(new Module() {
            @Override
            public void configure(Binder binder) {
                binder.bind(Dog.class).toInstance(new BlackDog());
            }
        });

        Dog dog = injector.getInstance(Dog.class);
        dog.bark();
    }

可以看到Dog接口已经与某个BlackDog的实例绑定起来了。

3. 利用Provider的依赖注入

    public static void main(String[] args) {
        Injector injector = Guice.createInjector(new Module() {
            @Override
            public void configure(Binder binder) {
                binder.bind(Dog.class).toProvider(new Provider<Dog>() {
                    Dog dog = new BlackDog();

                    @Override
                    public Dog get() {
                        return dog;
                    }
                });
            }
        });

        Dog dog = injector.getInstance(Dog.class);
        dog.bark();
    }

换了一种方法的绑定,在自定义的Provider类中,我们可以执行一些复杂的操作。

4. 基于注解的依赖注入

可以在接口上添加@ImplementedBy完成绑定操作

@ImplementedBy(BlackDog.class)
public interface Dog {
    void bark();
}

public class BlackDog implements Dog{
    @Override
    public void bark() {
        System.out.println("i am black dog");
    }
}

public class GuiceTest {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        Dog dog = injector.getInstance(Dog.class);
        dog.bark();
    }
}

可以看到没有为Guice指定任何Module,也完成了依赖注入的操作

当然,也可以用@ProvidedBy注解完成绑定操作

@ProvidedBy(BlackDogProvider.class)
public interface Dog {
    void bark();
}

public class BlackDogProvider implements Provider<Dog> {
    @Override
    public Dog get() {
        return new BlackDog();
    }
}

public class GuiceTest {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        Dog dog = injector.getInstance(Dog.class);
        dog.bark();
    }
}

基于注解的依赖注入其实与基于Module的依赖注入差别不大,只是口味上的区别

但是Module里的配置会覆盖注解里的配置

5. 单例

在默认情况下,每次调用getInstance方法,都会创建一个新的对象并返回(Provider注入与实例注入除外)

@ImplementedBy(BlackDog.class)
public interface Dog {
    void bark();
}

public class BlackDog implements Dog{
    @Override
    public void bark() {
        System.out.println("i am black dog");
    }
}

public class GuiceTest {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        for (int i = 0; i < 10; i++) {
            System.out.println(injector.getInstance(Dog.class).hashCode());
        }
    }
}

调用10次getInstance方法,分别计算得到对象的hashCode,结果如下

1709366259
1335298403
1643691748
2068434592
143110009
2142003995
1535634836
1846412426
1539805781
1206883981

可以看出,每次调用getInstance方法,都会生成一个全新的对象。

如果我们希望返回的是同一个对象(单例模式),那么只需要在实现类上加一个@Singleton注解

@ImplementedBy(BlackDog.class)
public interface Dog {
    void bark();
}

@Singleton
public class BlackDog implements Dog{
    @Override
    public void bark() {
        System.out.println("i am black dog");
    }
}

public class GuiceTest {
    public static void main(String[] args) {
        Injector injector = Guice.createInjector();
        for (int i = 0; i < 10; i++) {
            System.out.println(injector.getInstance(Dog.class).hashCode());
        }
    }
}

运行结果如下:

1632492873
1632492873
1632492873
1632492873
1632492873
1632492873
1632492873
1632492873
1632492873
1632492873

可以看到@Singleton注解已经生效,调用getInstance方法返回的对象已经是单例的了

6. 单接口多实现类

时间: 2024-11-03 03:26:09

Guice 4.1教程的相关文章

Guice源码学习(一)基本原理

Guice是Google开发的一个开源轻量级的依赖注入框架,运行速度快,使用简单. 项目地址:https://github.com/google/guice/ 最新的版本是4.1,本文基于此版本. Guice的使用方法请参见我的前篇博文:<Guice 4.1教程> 0. Guice的使用范例 先分析最简单的例子 public interface Dog { void bark(); } public class BlackDog implements Dog{ @Override public

Google Guice 入门教程

01 - 依赖注入 1. 依赖注入 1.1 类依赖注入 所谓的绑定就是将一个接口绑定到具体的类中,这样客户端不用关心具体的实现,而只需要获取相应的接口完成其服务即可. HelloWorld.java 1     public interface HelloWorld { 2 3         String sayHello(); 4     } 5 然后是具体的实现,HelloWorldImpl.java 1     public class HelloWorldImpl implements

超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享

原创不易,转载请注明出处:超轻量级DI容器框架Google Guice与Spring框架的区别教程详解及其demo代码片段分享 代码下载地址:http://www.zuidaima.com/share/1759689106541568.htm 依赖注入,DI(Dependency Injection),它的作用自然不必多说,提及DI容器,例如spring,picoContainer,EJB容器等等,近日,google诞生了更轻巧的DI容器--Guice! 废话不多讲了,先看看Guice是如何实现

Google Guice 系列教程 - 基础实践

转载:http://www.cnblogs.com/youngC/archive/2012/12/21/2828419.html 前言 Google Guice 是一个轻量级的依赖注入框架,它支持Java 5或者更高版本的JDK,得利于Java 5中提供的泛型 (Generics) 和注释 (Annotations) ,它可以使得代码类型安全 (type-safe) .那么何时使用在代码中使用 Guice 进行注入呢?一般来说,如果在你的应用代码中业务对象 (Business Objects)

Guice入门

参考链接:http://www.cnblogs.com/xd502djj/archive/2012/06/25/2561414.html Google Guice范例解说之使用入门 http://code.google.com/p/google-guice/ Google公司的Bob lee开发的轻量级IoC容器,其特点是: 1.速度快,号称是spring的100倍速度 2.无配置文件,实用JDK5.0的annotation描述组件依赖,简单,而且有编译器检查和重构支持 3.简单,代码量很少 h

Intellij IDEA教程.pdf

http://pan.baidu.com/s/1dDEaVxn 目录 Intellij IDEA 教程 ............................................................................................................................... 2 安装配置 ...............................................................

Spark教程——(11)Spark程序本地执行和集群执行的差异

本地执行Spark SQL程序: package com.fc //import common.util.{phoenixConnectMode, timeUtil} import org.apache.spark.sql.SQLContext import org.apache.spark.sql.functions.col import org.apache.spark.{SparkConf, SparkContext} /* 每天执行 */ object costDay { def mai

Windows Git+TortoiseGit简易使用教程

转载自 http://blog.csdn.net/jarelzhou/article/details/8256139 官方教程:http://tortoisegit.org/docs/tortoisegit/(英文版) 为什么选择Git 效率 很多人有一种习惯吧,什么软件都要最新的,最好的.其实吧,软件就是工具,生产力工具,为的是提高我们的生产力.如果现有的工具已经可以满足生产力要求了,就没有必要换了.生产效率高低应当是选择工具的第一位. 历史 开源世界的版本控制系统,经历了这么几代: 第一代,

微信公众号中添加外部链接地址的图文教程

2017-9-18,长沙,有点闷,有点热. 本教程教大家如何在微信公众号中,添加外部的链接,网络有很多教程,但由于表述不太清楚,出个教程吧.最终实现在微信后台管理平台"原文链接"处插入外部链接,用户点击发布好的图文文章底部左下角的"阅读原文",就可以跳转到您添加的外部链接页面中去. 第1步. 使用微信公众管理帐号登陆微信管理后台 > 素材管理 > 图文消息 >  新建图文消息或者编辑文章都可以,如下图所示: 第2步. 之后,将页面向下拉,看到底部&