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

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

阅读更多

本章节继续讨论依赖注入的其他话题,包括作用域(scope,这里有一个与线程绑定的作用域例子)、立即初始化(Eagerly Loading Bindings)、运行阶段(Stage)、选项注入(Optional Injection)等等。 

1.3.5 Scope(作用域)

在1.1章节中我们初步了解了对象的单例模式,在Guice中提供了一些常见的作用域,比如对于单例模式有下面两个作用域。

 

    com.google.inject.Scopes.SINGLETON

    com.google.inject.Scopes.NO_SCOPE

在使用上,可以使用Module的bind来实现,看下面的例子。

 

 1     public class ScopeDemo {
 2         public static void main(String[] args) {
 3 
 4             Service service = Guice.createInjector(new Module() {
 5                 @Override
 6                 public void configure(Binder binder) {
 7                     binder.bind(Service.class).to(WwwService.class).in(Scopes.SINGLETON);
 8                 }
 9             }).getInstance(Service.class);
10             service.execute();
11         }
12     }
13 
14 

当然单例模式还可以似乎用@Singleton注解。

在com.google.inject.binder.ScopedBindingBuilder.in(Scope)方法中,一个Scope除了可以使上面的SINGLETION和NO_SCOPE外,还可以是自己定义的Scope。下面的例子演示了一个与线程绑定的Scope例子。

 1 /**
 2  * $Id: ThreadScopeDemo.java 90 2009-12-25 08:12:21Z 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.Injector;
10 import com.google.inject.Key;
11 import com.google.inject.Module;
12 import com.google.inject.Provider;
13 import com.google.inject.Scope;
14 
15 /** a demo with thread-scope
16  * @author 
17  * @version $Rev: 90 $
18  */
19 public class ThreadScopeDemo {
20 
21     static class ThreadServiceScope implements Scope {
22 
23         static ThreadLocal<Object> threadLocal = new ThreadLocal<Object>();
24 
25         @Override
26         public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
27             return new Provider<T>() {
28                 @Override
29                 public T get() {
30                     T instance = (T) threadLocal.get();
31                     if (instance == null) {
32                         instance = unscoped.get();
33                         threadLocal.set(instance);
34                     }
35                     return instance;
36                 }
37             };
38         }
39 
40         @Override
41         public String toString() {
42             return "Scopes.ThreadServiceScope";
43         }
44     }
45     
46     public static void main(String[] args) {
47         final Injector inj=Guice.createInjector(new Module() {
48             @Override
49             public void configure(Binder binder) {
50                 binder.bind(Service.class).to(WwwService.class).in(new ThreadServiceScope());
51             }
52         });
53         for(int i=0;i<3;i++) {
54             new Thread("Thread-"+i) {
55                 public void run() {
56                     for(int m=0;m<3;m++) {
57                         System.out.println(String.format("%s-%d:%d",//
58                                 getName()//
59                                 ,m//
60                                 ,inj.getInstance(Service.class).hashCode()));
61                         try {
62                             Thread.sleep(50L);
63                         } catch (Exception e) {
64                         }
65                     }
66                 }
67             }.start();
68         }
69     }
70 }
71 

 

注意,这里用到了《Google Guice 入门教程03 - 依赖注入》的中的两个类Service和WwwService。在本例中ThreadServiceScope类是一个与线程绑定的作用域(利用ThreadLocal特性),当当前线程中没有构造一个对象的时候先构造一个出来,然后放入线程上下文中,以后每次都从线程中获取对象。第50行是将WwwService服务以ThreadServiceScope的作用域绑定到Service服务上。第57-60行输出当前对象的hashCode,如果此类是同一对象的话就应该输出相同的hashCode。为了看到效果,我们使用3个线程,每个线程输出三次来看结果。

Thread-0-0:18303751
Thread-1-0:23473608
Thread-2-0:21480956
Thread-1-1:23473608
Thread-0-1:18303751
Thread-2-1:21480956
Thread-1-2:23473608
Thread-2-2:21480956
Thread-0-2:18303751

 

我们看到对于同一个线程(比如说Thread-0)的三次都输出了相同的对象(hashCode为18303751),而与线程2和线程3的hashCode不同。

(特别说明:如果两个线程输出了同一个hashCode不必惊慌,那是因为可能前一个线程生成的对象的地址空间被GC释放了,结果下一个线程使用了上一个线程的相同空间,所以这里使用Thread.sleep来降低这种可能性)

事实上在guice-servlet-2.0.jar中有与request和session绑定的scope。

com.google.inject.servlet.ServletScopes.REQUEST
com.google.inject.servlet.ServletScopes.SESSION

 

1.3.6 Eagerly Loading Bindings (立即初始化)

除了可以绑定scope外,对象默认在第一次调用时被创建,也即所谓的延时加载,Guice也允许对象在注入到Guice容器中时就被创建出来(显然这是针对单例模式才有效)。

 1 public class EagerSingletonDemo {
 2 
 3     public EagerSingletonDemo() {
 4         System.out.println(" constuctor:"+System.nanoTime());
 5     }
 6     void doit() {
 7         System.out.println("       doit:"+System.nanoTime());
 8     }
 9     public static void main(String[] args) throws Exception{
10         Injector inj = Guice.createInjector(new Module() {
11             @Override
12             public void configure(Binder binder) {
13                 binder.bind(EagerSingletonDemo.class).asEagerSingleton();
14             }
15         });
16         System.out.println("before call:"+System.nanoTime());
17         Thread.sleep(100L);
18         inj.getInstance(EagerSingletonDemo.class).doit();
19     }
20 }

 

结果输出如下:

 constuctor:26996967388652
before call:
26996967713635
       doit:
26997069993702

 

可以看到我们的对象在调用getInstance之前就已经被构造出来了。

1.3.7 Stages (运行阶段)

Guice还有一个特效,可以指定Guice运行模式来控制Guice的加载速度。在com.google.inject.Stage枚举中提供了TOOL,DEVELOPMENT,PRODUCTION三种模式。

TOOL描述的是带有IDE等插件的运行模式;DEVELOPMENT是指在开发阶段只加载自己需要的功能(对于非立即初始化单例对象采用延后加载),这样来降低加载不需要功能的时间;而PRODUCTION模式是指完全加载所有功能(对于单例对象采用立即加载方式),这样可以更早的发现问题,免得等需要某些功能的时候才发现问题(要知道我们某些功能可能需要特定的条件才能触发)。

其实只有比较多的单例对象,并且单例对象构造比较耗时的情况下才能有用。大部分情况下这点性能可能都忽略不计了。

默认情况下Guice采用DEVELOPMENT模式。

 

1.3.8 Optional Injection (选项注入 )

选项注入描述的是如果不能从Guice容器中注入一个对象,那么可以使用一个默认的对象。看下面的例子。

 1 public class OptionalInjectionDemo {
 2     @Inject(optional=true)
 3     Service service = new WwwService();
 4     public static void main(String[] args) {
 5         Guice.createInjector(new Module() {
 6             public void configure(Binder binder) {
 7                 //binder.bind(Service.class).to(HomeService.class);
 8             }
 9         }).getInstance(OptionalInjectionDemo.class).service.execute();
10     }
11 }

 

上述例子中第2行描述的是选项注入,如果不能从Guice容器中获取一个Service服务那么就使用默认的WwwService,否则就是用获取的服务。如果将第7行注释去掉我们就可以看到实际上调用的是HomeService服务了。

 

到此为止,Guice依赖注入的基本教程就学习完了,下面的章节我们进入经典的AOP教程学习。

分享到:
评论

相关推荐

    guice-assistedinject-3.0-API文档-中英对照版.zip

    赠送Maven依赖信息文件:guice-assistedinject-3.0.pom; 包含翻译后的API文档:guice-assistedinject-3.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:...

    guice-assistedinject-3.0-API文档-中文版.zip

    赠送Maven依赖信息文件:guice-assistedinject-3.0.pom; 包含翻译后的API文档:guice-assistedinject-3.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.google.inject.extensions:guice-assistedinject:3.0...

    guice-multibindings-3.0-API文档-中英对照版.zip

    赠送Maven依赖信息文件:guice-multibindings-3.0.pom; 包含翻译后的API文档:guice-multibindings-3.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:...

    guice-multibindings-3.0-API文档-中文版.zip

    赠送Maven依赖信息文件:guice-multibindings-3.0.pom; 包含翻译后的API文档:guice-multibindings-3.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.google.inject.extensions:guice-multibindings:3.0; ...

    guice-servlet-4.0-API文档-中文版.zip

    赠送Maven依赖信息文件:guice-servlet-4.0.pom; 包含翻译后的API文档:guice-servlet-4.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.google.inject.extensions:guice-servlet:4.0; 标签:google、...

    guice-servlet-4.0-API文档-中英对照版.zip

    赠送Maven依赖信息文件:guice-servlet-4.0.pom; 包含翻译后的API文档:guice-servlet-4.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.google.inject.extensions:guice-servlet:4.0; 标签:...

    guice-4.0-API文档-中文版.zip

    赠送Maven依赖信息文件:guice-4.0.pom; 包含翻译后的API文档:guice-4.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.google.inject:guice:4.0; 标签:google、inject、guice、中文文档、jar包、java; ...

    guice-4.0-API文档-中英对照版.zip

    赠送Maven依赖信息文件:guice-4.0.pom; 包含翻译后的API文档:guice-4.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.google.inject:guice:4.0; 标签:google、inject、guice、中英对照文档、...

    guice-3.0-API文档-中文版.zip

    赠送Maven依赖信息文件:guice-3.0.pom; 包含翻译后的API文档:guice-3.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.google.inject:guice:3.0; 标签:google、inject、guice、jar包、java、中文文档; ...

    guice-3.0-API文档-中英对照版.zip

    赠送Maven依赖信息文件:guice-3.0.pom; 包含翻译后的API文档:guice-3.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.google.inject:guice:3.0; 标签:google、inject、guice、jar包、java、...

    guice超轻量级依赖注入

    guice超轻量级依赖注入用了才知道是爽

    guice-struts2-plugin-1.0.1.jar

    google-guice struts2-plugin

    sisu-guice-2.1.7-noaop.jar

    sisu-guice-2.1.7-noaop.jar

    guice-spring-1.0.jar

    guice-spring-1.0.jar

    shiro-guice-1.4.0-API文档-中文版.zip

    赠送Maven依赖信息文件:shiro-guice-1.4.0.pom; 包含翻译后的API文档:shiro-guice-1.4.0-javadoc-API文档-中文(简体)版.zip; Maven坐标:org.apache.shiro:shiro-guice:1.4.0; 标签:apache、shiro、guice、...

    jersey-guice-1.19-API文档-中文版.zip

    赠送Maven依赖信息文件:jersey-guice-1.19.pom; 包含翻译后的API文档:jersey-guice-1.19-javadoc-API文档-中文(简体)版.zip; Maven坐标:com.sun.jersey.contribs:jersey-guice:1.19; 标签:sun、jersey、...

    shiro-guice-1.4.0-API文档-中英对照版.zip

    赠送Maven依赖信息文件:shiro-guice-1.4.0.pom; 包含翻译后的API文档:shiro-guice-1.4.0-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:org.apache.shiro:shiro-guice:1.4.0; 标签:apache、shiro、...

    jersey-guice-1.19-API文档-中英对照版.zip

    赠送Maven依赖信息文件:jersey-guice-1.19.pom; 包含翻译后的API文档:jersey-guice-1.19-javadoc-API文档-中文(简体)-英语-对照版.zip; Maven坐标:com.sun.jersey.contribs:jersey-guice:1.19; 标签:sun、...

    guice-servlet-3.0.jar

    guice-servlet-3.0.jar

Global site tag (gtag.js) - Google Analytics