本章节继续讨论依赖注入的其他话题,包括作用域(scope,这里有一个与线程绑定的作用域例子)、立即初始化(Eagerly Loading Bindings)、运行阶段(Stage)、选项注入(Optional Injection)等等。
1.3.5 Scope(作用域)
在1.1章节中我们初步了解了对象的单例模式,在Guice中提供了一些常见的作用域,比如对于单例模式有下面两个作用域。
com.google.inject.Scopes.NO_SCOPE
在使用上,可以使用Module的bind来实现,看下面的例子。
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例子。
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-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.SESSION
1.3.6 Eagerly Loading Bindings (立即初始化)
除了可以绑定scope外,对象默认在第一次调用时被创建,也即所谓的延时加载,Guice也允许对象在注入到Guice容器中时就被创建出来(显然这是针对单例模式才有效)。
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 }
结果输出如下:
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容器中注入一个对象,那么可以使用一个默认的对象。看下面的例子。
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是Google开发的一个轻量级依赖注入框架,它通过注解来管理对象的生命周期和依赖关系,简化Java应用的构建和测试。 描述中的"slicer.zip"可能是一个与CSV处理相关的子项目或者模块,其主要功能是读取和过滤CSV...
在"Guice入门教程HelloWorld篇"中,我们将学习如何使用Guice来构建简单的Java应用程序。首先,我们需要理解Guice的核心概念——模块(Module)和绑定(Binding)。模块是Guice配置的核心,它定义了哪些类应该被实例...
### Google Guice: 敏捷轻量级依赖注入框架详解 #### 一、引言与背景 在现代软件开发中,依赖注入(Dependency Injection, DI)已成为构建灵活、可维护和可测试应用程序的重要手段之一。Google Guice作为一款100%...
Guice是一个轻量级的依赖注入框架,由Google开发,它使得Java开发者能够更方便地管理对象之间的依赖关系,从而简化代码结构,提高可测试性和可维护性。 描述中提到的"reportng"是TestNG的一个增强插件,专门用于...
Guice是Google开发的一个轻量级,基于Java5(主要运用泛型与注释特性)的依赖注入框架(IOC)。Guice非常小而且快。Guice是类型安全的,它能够对构造函数,属性,方法(包含任意个参数的任意方法,而不仅仅是setter...
#### 四、Guice入门 Guice通过使用`@Inject`注解来自动注入依赖项,这使得代码更简洁且易于理解。例如,如果有一个`UserService`类依赖于`UserRepository`,可以这样定义: ```java public class UserService { ...
**Google Guice**,全称为Google Injection,是一个轻量级的依赖注入框架,它通过注解(Annotations)来实现对象的自动装配,简化了Java应用的构造和管理。Guice的核心理念是帮助开发者摆脱手动创建对象和管理对象...
【标题】:“Cucumber-Guice-1.1.4.zip”是一个开源项目,它将Cucumber测试框架与Google的依赖注入库Guice相结合。Cucumber是一个行为驱动开发(BDD)工具,允许非技术人员通过自然语言编写测试场景,而Guice则是一...
在本实例中,我们将深入探讨如何将Google的依赖注入框架Guice与Struts2整合,以实现更高效、更灵活的代码管理。 在Java Web开发中,依赖注入(DI)是一种设计模式,它可以帮助我们降低组件之间的耦合,使得测试和...
Guice 是 Google 推出的一款轻量级的依赖注入框架,专为 Java 5 及其后续版本设计。依赖注入(Dependency Injection,简称 DI)是一种设计模式,它允许开发者在不直接创建对象的情况下,将依赖关系从代码中解耦出来...
《Google Guice:敏捷轻量级依赖注入框架》是一本深度探索Google Guice框架的专著,由Robbie Vanbrabant撰写,旨在帮助读者全面掌握这一先进的依赖注入技术。本书共180页,提供了PDF电子书和按需打印两种版本,是...
FindBugs-Guice是这样一款开源项目,它将FindBugs这一强大的静态分析工具与Google的依赖注入框架Guice相结合,帮助开发者在代码执行之前发现并修复潜在问题。本文将深入探讨FindBugs-Guice的核心功能、工作原理以及...
在 DropWizard-Guice-Redis 项目中,Guice 是Google提供的轻量级依赖注入框架。依赖注入(Dependency Injection,简称DI)是一种设计模式,它有助于减少代码之间的耦合,提高代码的可测试性和可维护性。Guice 通过...
khsSherpa 的 Google Guice 依赖注入集成。 此处链接到 khsSherpa 项目...[ ] 入门 要使其正常工作,请按照下列步骤操作: 添加 <listener>com.khs.guice.SherpaGuiceContextListener</listener> 在 Sherpa ...
Dropwizard是一个用于构建高性能、生产级Java web服务的工具集,而Guice是Google开发的一个轻量级依赖注入框架。这个压缩包可能是为了解决在Dropwizard应用中集成Guice,以实现更灵活的组件管理和配置。 Dropwizard...
Guice,由Google开发的一款轻量级依赖注入框架,是Java平台上的一个关键工具,用于简化应用程序的构建和管理。依赖注入(Dependency Injection,DI)是一种设计模式,它可以帮助我们编写松散耦合、可测试且易于维护...
NFSDB通常是一种分布式、高性能的数据库系统,而Guice则是Google开发的一个轻量级依赖注入框架,用于简化Java应用的构建和测试。 【描述】"org.liveSense.framework.xdocreport.zip, LiveSense xdocreport框架" ...
Roboguice是一个轻量级的依赖注入库,它基于Google的Guice框架,并针对Android进行了优化。通过注解(Annotations)的方式,开发者可以方便地管理对象的生命周期和它们之间的依赖关系。 1. **Roboguice的安装与配置...
而 Google 的 Guice 则是一个流行的依赖注入框架,它简化了对象的创建和管理过程。本文将详细介绍如何将 Apache Shiro 集成到基于 Guice 的应用中。 #### Apache Shiro 与 Guice 集成概述 自 Shiro 1.2 版本起,...