`
wbj0110
  • 浏览: 1601036 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Google Guice 入门教程03 - 依赖注入

阅读更多

1.3 更多话题

1.3.1 接口多实现

如果一个接口有多个实现,这样通过@Inject和Module都难以直接实现,但是这种现象确实是存在的,于是Guice提供了其它注入方式来解决此问题。比如下面的自定义注解。

 

1     public interface Service {
2 
3         void execute();
4     }
5 
6 

 

1 public class HomeService implements Service {
2     @Override
3     public void execute() {
4         System.out.println("home.imxylz.cn");
5     }
6 }

 

1 public class WwwService implements Service {
2     @Override
3     public void execute() {
4         System.out.println("www.imxylz.cn");
5     }
6 }

 

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target({FIELD,PARAMETER})
3 @BindingAnnotation
4 public @interface Home {
5 }

 

1 @Retention(RetentionPolicy.RUNTIME)
2 @Target({FIELD,PARAMETER})
3 @BindingAnnotation
4 public @interface Www {
5 }


上面的代码描述的是一个Service服务,有WwwService和HomeService两个实现,同时有Www和Home两个注解(如果对注解各个参数不明白的需要单独去学习JAVA 5注解)。好了下面请出我们的主角。

 1     /**
 2      * $Id: MultiInterfaceServiceDemo.java 82 2009-12-24 06:55:16Z xylz $
 3      * xylz study project
 4      */
 5     package cn.imxylz.study.guice.inject.more;
 6 
 7     import com.google.inject.Binder;
 8     import com.google.inject.Guice;
 9     import com.google.inject.Inject;
10     import com.google.inject.Module;
11 
12     /** a demo with multi interfaces
13      * @author 
14      * @version $Rev: 82 $
15      */
16     public class MultiInterfaceServiceDemo {
17         @Inject
18         @Www
19         private Service wwwService;
20         @Inject
21         @Home
22         private Service homeService;
23         public static void main(String[] args) {
24             MultiInterfaceServiceDemo misd = Guice.createInjector(new Module() {
25                 @Override
26                 public void configure(Binder binder) {
27                     binder.bind(Service.class).annotatedWith(Www.class).to(WwwService.class);
28                     binder.bind(Service.class).annotatedWith(Home.class).to(HomeService.class);
29                 }
30             }).getInstance(MultiInterfaceServiceDemo.class);
31             misd.homeService.execute();
32             misd.wwwService.execute();
33         }
34     }
35 
36 

 

此类的结构是注入两个Service服务,其中wwwService是注入@Www注解关联的WwwService服务,而homeService是注入@Home注解关联的HomeService服务。

同样关于此结构我们要问几个问题。

问题(1)静态注入多个服务怎么写?

其实,参照教程02,我们可以使用下面的例子。

 

 1 public class StaticMultiInterfaceServiceDemo {
 2     @Inject
 3     @Www
 4     private static Service wwwService;
 5     @Inject
 6     @Home
 7     private static Service homeService;
 8     public static void main(String[] args) {
 9        Guice.createInjector(new Module() {
10             @Override
11             public void configure(Binder binder) {
12                 binder.bind(Service.class).annotatedWith(Www.class).to(WwwService.class);
13                 binder.bind(Service.class).annotatedWith(Home.class).to(HomeService.class);
14                 binder.requestStaticInjection(StaticMultiInterfaceServiceDemo.class);
15             }
16         });
17         StaticMultiInterfaceServiceDemo.homeService.execute();
18         StaticMultiInterfaceServiceDemo.wwwService.execute();
19     }
20 }

问题(2):如果不小心一个属性绑定了多个接口怎么办?

非常不幸,你将得到类似一下的错误,也就是说不可以绑定多个服务。

 

1) cn.imxylz.study.guice.inject.more.StaticMultiInterfaceServiceDemo.wwwService has more than one annotation annotated with @BindingAnnotation: cn.imxylz.study.guice.inject.more.Www and cn.imxylz.study.guice.inject.more.Home
  at cn.imxylz.study.guice.inject.more.StaticMultiInterfaceServiceDemo.wwwService(StaticMultiInterfaceServiceDemo.java:
17)

问题(3):我太懒了不想写注解来区分多个服务,怎么办?

程序员都是懒惰的,于是Google帮我们提供了一个Names的模板来生成注解。看下面的例子。

 

 1 public class NoAnnotationMultiInterfaceServiceDemo {
 2     @Inject
 3     @Named("Www")
 4     private static Service wwwService;
 5     @Inject
 6     @Named("Home")
 7     private static Service homeService;
 8     public static void main(String[] args) {
 9        Guice.createInjector(new Module() {
10             @Override
11             public void configure(Binder binder) {
12                 binder.bind(Service.class).annotatedWith(Names.named("Www")).to(WwwService.class);
13                 binder.bind(Service.class).annotatedWith(Names.named("Home")).to(HomeService.class);
14                 binder.requestStaticInjection(NoAnnotationMultiInterfaceServiceDemo.class);
15             }
16         });
17         NoAnnotationMultiInterfaceServiceDemo.homeService.execute();
18         NoAnnotationMultiInterfaceServiceDemo.wwwService.execute();
19     }
20 }

上面的例子中我们使用Named来标注我们的服务应该使用什么样的注解,当然前提是我们已经将相应的服务与注解关联起来了。

1.3.2 Provider注入

在教程第一篇中我们提到了可以通过Provider注入一个服务,这里详细说说这种模式。

首先我们需要构造一个Provider<T>出来。

 

1     public class WwwServiceProvider implements Provider<Service> {
2 
3         @Override
4         public Service get() {
5             return new WwwService();
6         }
7     }
8 
9 

上面的Provider的意思很简单,每次新建一个新的WwwService对象出来。

注入的过程看下面的代码。

 

 1     public class ProviderServiceDemo {
 2 
 3         @Inject
 4         private Service service;
 5 
 6         public static void main(String[] args) {
 7             Injector inj=  Guice.createInjector(new Module() {
 8                 @Override
 9                 public void configure(Binder binder) {
10                     binder.bind(Service.class).toProvider(WwwServiceProvider.class);
11                 }
12             });
13             ProviderServiceDemo psd = inj.getInstance(ProviderServiceDemo.class);
14             psd.service.execute();
15         }
16 
17     }
18 
19 

很显然如果这东西和线程绑定就非常好了,比如我们可以使用ThreadLocal来做线程的对象交换。

当然如果想自动注入(不使用Module手动关联)服务的话,可以使用@ProviderBy注解。

 

1     @ProvidedBy(WwwServiceProvider.class)
2     public interface Service {
3 
4         void execute();
5     }
6 
7 

这样我们就不必使用Module将Provider绑定到Service上,获取服务就很简单了。

 

ProviderServiceDemo psd = Guice.createInjector().getInstance(ProviderServiceDemo.class);
psd.service.execute();

除了上述两种方式我们还可以注入Provider,而不是注入服务,比如下面的例子例子中,属性不再是Service,而是一个Provider<Service>。

 

 1     public class ProviderServiceDemo {
 2 
 3         @Inject
 4         private Provider<Service> provider;
 5 
 6         public static void main(String[] args) {
 7             ProviderServiceDemo psd = Guice.createInjector(new Module() {
 8                 @Override
 9                 public void configure(Binder binder) {
10                     binder.bind(Service.class).toProvider(WwwServiceProvider.class);
11                 }
12             }).getInstance(ProviderServiceDemo.class);
13             psd.provider.get().execute();
14         }
15     }
16 
17 

当然了,由于我们WwwServiceProvider每次都是构造一个新的服务出来,因此在类ProviderServiceDemo中的provider每次获取的服务也是不一样的。

1.3.3 绑定常量

看看下面的例子,演示了一个绑定整数值到实例的例子。

 

 1     public class ConstantInjectDemo {
 2 
 3         @Inject
 4         @Named("v")
 5         private int v;
 6         public static void main(String[] args) {
 7 
 8             ConstantInjectDemo cid = Guice.createInjector(new Module() {
 9                 @Override
10                 public void configure(Binder binder) {
11                     binder.bindConstant().annotatedWith(Names.named("v")).to(12);
12                 }
13             }).getInstance(ConstantInjectDemo.class);
14             System.out.println(cid.v);
15         }
16     }
17 
18 

当然,既然可以使用Named,也就可以使用自己写注解了。但是看起来好像没有多大作用。除了上述写法,也可以用下面的方式实现。

binder.bind(int.class).annotatedWith(Names.named("v")).toInstance(12);

除了可以绑定int外,在ConstantBindingBuilder类中还可以绑定其它的基本类型。

com.google.inject.binder.ConstantBindingBuilder.to(String)
com.google.inject.binder.ConstantBindingBuilder.to(
long)
com.google.inject.binder.ConstantBindingBuilder.to(
boolean)
com.google.inject.binder.ConstantBindingBuilder.to(
double)
com.google.inject.binder.ConstantBindingBuilder.to(
float)
com.google.inject.binder.ConstantBindingBuilder.to(
short)
com.google.inject.binder.ConstantBindingBuilder.to(
char

 

1.3.4 绑定Properties

除了可以绑定基本类型外,还可以绑定一个Properties到Guice中,当然了,由于Properties本质上时一个Map<String,String>,因此Guice也允许绑定一个Map<String,String>。

 

 1     @Inject
 2     @Named("web")
 3     private String web;
 4 
 5     public static void main(String[] args) {
 6 
 7         ConstantInjectDemo cid = Guice.createInjector(new Module() {
 8             @Override
 9             public void configure(Binder binder) {
10                 Properties properties= new Properties();
11                 properties.setProperty("web""www.imxylz.cn");
12                 Names.bindProperties(binder, properties);
13             }
14         }).getInstance(ConstantInjectDemo.class);
15         System.out.println(cid.web);
16     }
17 
18 
分享到:
评论

相关推荐

    wink-guice-server-1.2.1-incubating.zip

    Guice是Google开发的一个轻量级依赖注入框架,它通过注解来管理对象的生命周期和依赖关系,简化Java应用的构建和测试。 描述中的"slicer.zip"可能是一个与CSV处理相关的子项目或者模块,其主要功能是读取和过滤CSV...

    guice入门教程helloworld篇

    在"Guice入门教程HelloWorld篇"中,我们将学习如何使用Guice来构建简单的Java应用程序。首先,我们需要理解Guice的核心概念——模块(Module)和绑定(Binding)。模块是Guice配置的核心,它定义了哪些类应该被实例...

    Google Guice: Agile Lightweight Dependency Injection Framework

    ### Google Guice: 敏捷轻量级依赖注入框架详解 #### 一、引言与背景 在现代软件开发中,依赖注入(Dependency Injection, DI)已成为构建灵活、可维护和可测试应用程序的重要手段之一。Google Guice作为一款100%...

    guice-3.0.jar.zip

    Guice是一个轻量级的依赖注入框架,由Google开发,它使得Java开发者能够更方便地管理对象之间的依赖关系,从而简化代码结构,提高可测试性和可维护性。 描述中提到的"reportng"是TestNG的一个增强插件,专门用于...

    google guice基础例子

    Guice是Google开发的一个轻量级,基于Java5(主要运用泛型与注释特性)的依赖注入框架(IOC)。Guice非常小而且快。Guice是类型安全的,它能够对构造函数,属性,方法(包含任意个参数的任意方法,而不仅仅是setter...

    Guice教程(Google)

    #### 四、Guice入门 Guice通过使用`@Inject`注解来自动注入依赖项,这使得代码更简洁且易于理解。例如,如果有一个`UserService`类依赖于`UserRepository`,可以这样定义: ```java public class UserService { ...

    Google guice

    **Google Guice**,全称为Google Injection,是一个轻量级的依赖注入框架,它通过注解(Annotations)来实现对象的自动装配,简化了Java应用的构造和管理。Guice的核心理念是帮助开发者摆脱手动创建对象和管理对象...

    cucumber-guice-1.1.4.zip

    【标题】:“Cucumber-Guice-1.1.4.zip”是一个开源项目,它将Cucumber测试框架与Google的依赖注入库Guice相结合。Cucumber是一个行为驱动开发(BDD)工具,允许非技术人员通过自然语言编写测试场景,而Guice则是一...

    Struts2的第一个入门实例(三)--Struts2与Guice整合

    在本实例中,我们将深入探讨如何将Google的依赖注入框架Guice与Struts2整合,以实现更高效、更灵活的代码管理。 在Java Web开发中,依赖注入(DI)是一种设计模式,它可以帮助我们降低组件之间的耦合,使得测试和...

    Guice 中文文档 例子

    Guice 是 Google 推出的一款轻量级的依赖注入框架,专为 Java 5 及其后续版本设计。依赖注入(Dependency Injection,简称 DI)是一种设计模式,它允许开发者在不直接创建对象的情况下,将依赖关系从代码中解耦出来...

    Google.Guice.Agile.Lightweight.Dependency.Injection.Framework

    《Google Guice:敏捷轻量级依赖注入框架》是一本深度探索Google Guice框架的专著,由Robbie Vanbrabant撰写,旨在帮助读者全面掌握这一先进的依赖注入技术。本书共180页,提供了PDF电子书和按需打印两种版本,是...

    findbugs-guice-0.5.zip

    FindBugs-Guice是这样一款开源项目,它将FindBugs这一强大的静态分析工具与Google的依赖注入框架Guice相结合,帮助开发者在代码执行之前发现并修复潜在问题。本文将深入探讨FindBugs-Guice的核心功能、工作原理以及...

    DropWizard-Guice-Redis:带有 Guice 和 Redis 的简单 dropwizard 配置

    在 DropWizard-Guice-Redis 项目中,Guice 是Google提供的轻量级依赖注入框架。依赖注入(Dependency Injection,简称DI)是一种设计模式,它有助于减少代码之间的耦合,提高代码的可测试性和可维护性。Guice 通过...

    khs-sherpa-guice:夏尔巴人的 Guice 注入集成

    khsSherpa 的 Google Guice 依赖注入集成。 此处链接到 khsSherpa 项目...[ ] 入门 要使其正常工作,请按照下列步骤操作: 添加 &lt;listener&gt;com.khs.guice.SherpaGuiceContextListener&lt;/listener&gt; 在 Sherpa ...

    dropwizard-guice-0.6.2.zip

    Dropwizard是一个用于构建高性能、生产级Java web服务的工具集,而Guice是Google开发的一个轻量级依赖注入框架。这个压缩包可能是为了解决在Dropwizard应用中集成Guice,以实现更灵活的组件管理和配置。 Dropwizard...

    Guice使用练习

    Guice,由Google开发的一款轻量级依赖注入框架,是Java平台上的一个关键工具,用于简化应用程序的构建和管理。依赖注入(Dependency Injection,DI)是一种设计模式,它可以帮助我们编写松散耦合、可测试且易于维护...

    nfsdb-guice-1.0.2.zip

    NFSDB通常是一种分布式、高性能的数据库系统,而Guice则是Google开发的一个轻量级依赖注入框架,用于简化Java应用的构建和测试。 【描述】"org.liveSense.framework.xdocreport.zip, LiveSense xdocreport框架" ...

    安卓Android源码——用Roboguice实现依赖注入-.zip

    Roboguice是一个轻量级的依赖注入库,它基于Google的Guice框架,并针对Android进行了优化。通过注解(Annotations)的方式,开发者可以方便地管理对象的生命周期和它们之间的依赖关系。 1. **Roboguice的安装与配置...

    shiro,guice集成

    而 Google 的 Guice 则是一个流行的依赖注入框架,它简化了对象的创建和管理过程。本文将详细介绍如何将 Apache Shiro 集成到基于 Guice 的应用中。 #### Apache Shiro 与 Guice 集成概述 自 Shiro 1.2 版本起,...

Global site tag (gtag.js) - Google Analytics