`
polygoncell
  • 浏览: 55342 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

几个关于Guice的问题,关心Guice的请进

阅读更多
最近考虑在项目中使用guice,但是在替换一些Design patterns时遇到一些问题,特来这里向大家请教。

Guice的文档实在是太简单了,基本上就是几个简单的对象来回映射,对实际开发基本上没什么用。网上的例子也基本上停留在1+1=2的水平。

下面是我遇到的问题:

1. 如何在运行时态注入同一个对象的不同的实例?
   首先一个POJO:
 public class Foo {

    private boolean a;
    private boolean b;

    @inject
    public Foo(boolean a, boolean b) {
        this.a = a;
        this.b = b;
    }
} 


然后使用它:
public class FooContainer {

    @inject
    private Foo foo;

} 


我的问题是,Foo对象根据属性不同可以生成4中不同的实例,那么如何能够在runtime动态注入不同的实例呢?
另外,使用@Name注释可以绑定不同的实例,但是似乎无法动态绑定,而且如果类属性比较多的话,把每一种可能的实例都绑定起来,岂不是要吐血了。

2. 如何在runtime动态绑定任意对象?

 public class Foo {
           @inject
           private Object o;
     } 

这个例子里,Foo对象需要使用任意类型的对象实例,如何用Guice动态注入?类型为Object的对象实例为无限多,用@Name应该是解决不了问题了。

3. 如何解决传递对象问题?
   在API调用过程中,借助方法参数,可以将某一个对象实例在几个对象之间来回传递,而且它也不是singelton,这个被传递的对象不一定是Value Object。如果使用Guice的话如何实现?

4. 如何解决动态扩展的问题?
   为了便于理解,我举个简单的例子,MVC模式大家应该都很清楚,假如一个Control对应一个Model的话,用Guice可以完美实现。但是如果一个Control可以控制多个Model,而Model的数量是动态的,也就是说Control需要在runtime创建新的Model,同时还要保存已经存在的Models。针对这种情况,如何使用Guice注入?

5. 如何注入String?
   我刚刚开始接触Guice,估计用过Guice的朋友能够马上回答这个问题。先举个例子:
 public class Foo {

    @inject
    private String a;

    public Foo(String a) {
        this.a = a;
    }
} 


在使用Foo对象时,如何动态注入不同的String值?
其实这个问题和前面的几个问题类似,但是String是一个比较特殊的对象,所以单独拿出来提问。

6. 如何解决类关联的问题。例如:

public class Foo {

    private Bar bar;

    public Foo() {
        bar = new Bar(this);
    }

public class Bar {

    private Foo foo;

    public Bar(Foo foo) {
      this.foo = foo;
    }

如何保证使用guice注入后,bar中的foo是创建Bar的那个Foo对象实例?
分享到:
评论
6 楼 polygoncell 2008-04-15  
非常感谢,写了这么一大堆。:-)

这种做法和我考虑的一样,问题是这样也太麻烦了吧!
只是 new FooContainer(new Foo(true, false))和new FooContainer(new Foo(false, true))就能搞定的,结果用Guice写了这么多代码。

还有就是关于String的那个问题还存在。我再举例说明一下。在程序的某处需要Foo对象,例如Foo("ABC"), 过段时间,在其他地方又需要Foo("DEF"), 再过段时间,又需要Foo("XZY")就这样继续下去。。。。。。

我怎么用一个Foo类类实现这些映射?这些String之间并没有任何规律可循。
5 楼 xyz20003 2008-04-15  
ajoo说过一次,guice属于静态绑定,似乎做不到动态注入。

如果需要动态注入什么东西,可以用用一个Provider,动态放到provider里,然后再provider.get()取出来。
一个接口多个实例就是靠@Named
import com.google.inject.*;
import com.google.inject.name.Named;
import static com.google.inject.name.Names.*;

public class Main {

    @Inject
    @Named("blue")
    private Service blueService;

    @Inject
    @Named("green")
    private Service greenService;

    public static void main(String[] args) {
        Main main = Guice.createInjector(new Module() {
            public void configure(Binder binder) {
                binder.bind(Service.class).annotatedWith(named("blue"))
                                        .to(BlueServiceImpl.class);
                binder.bind(Service.class).annotatedWith(named("green"))
                                        .to(GreenServiceImpl.class);
            }
        }).getInstance(Main.class);

        main.blueService.hello();
        main.greenService.hello();
    }
}



String应该是可以当作constants常量直接注入的。

我们把guice的文档整理了一下,你可以看看:

http://www.family168.com/tutorial/guice/html/
4 楼 yujiang 2008-04-15  
写了点代码(不考虑Scope),估计会有点用.

import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.util.concurrent.atomic.AtomicInteger;

import com.google.inject.Binder;
import com.google.inject.BindingAnnotation;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.name.Named;
import com.google.inject.name.Names;

public class G {

	public static class Foo {
		boolean a;
		boolean b;

		@Inject
		@Named("random")
		Integer c;

		public Foo() {
		}

		public Foo(boolean a, boolean b) {
			this.a = a;
			this.b = b;
		}
	}

	public static class FooContainer {
		Foo foo = null;
	}

	@Target( { METHOD, CONSTRUCTOR, FIELD })
	@Retention(RUNTIME)
	@BindingAnnotation
	public static @interface A {

	}

	@Target( { METHOD, CONSTRUCTOR, FIELD })
	@Retention(RUNTIME)
	@BindingAnnotation
	public static @interface B {

	}

	@Inject
	@A
	FooContainer containerA = null;

	@Inject
	@B
	FooContainer containerB = null;

	public static void main(String[] args) {

		Injector injector = Guice.createInjector(new Module() {

			@Override
			public void configure(Binder binder) {

				binder.bind(Integer.class).annotatedWith(Names.named("random"))
						.toProvider(new Provider<Integer>() {

							AtomicInteger integer = new AtomicInteger(0);

							@Override
							public Integer get() {
								return integer.incrementAndGet();
							}
						});

				binder.bind(Foo.class).annotatedWith(Names.named("true-false"))
						.toInstance(new Foo(true, false));

				binder.bind(Key.get(Foo.class, Names.named("false-true")))
						.toProvider(new Provider<Foo>() {

							Foo foo = null;

							@Override
							public Foo get() {

								CHECK(foo.c != null, "foo.c != null");
								return foo;
							}

							@Inject
							public void setFoo(Foo foo) {

								this.foo = foo;
								foo.a = false;
								foo.b = true;
							}
						});

				binder.bind(Key.get(FooContainer.class, A.class)).toProvider(
						new Provider<FooContainer>() {
							
							@Inject
							@Named("true-false")
							Foo foo = null;

							@Inject
							FooContainer raw = null;

							@Override
							public FooContainer get() {

								raw.foo = foo;
								return raw;
							}
						});

				binder.bind(Key.get(FooContainer.class, B.class)).toProvider(
						new Provider<FooContainer>() {

							@Inject
							@Named("false-true")
							Foo foo = null;

							@Inject
							FooContainer raw = null;

							@Override
							public FooContainer get() {

								raw.foo = foo;
								return raw;
							}
						});

			}
		});

		G g = injector.getInstance(G.class);

		CHECK(g.containerA != g.containerB, "g.containerA != g.containerB");

		CHECK(g.containerA.foo.a == true, "g.containerA.foo.a == true");
		CHECK(g.containerA.foo.b == false, "g.containerA.foo.b == false");

		CHECK(g.containerB.foo.a == false, "g.containerB.foo.a == false");
		CHECK(g.containerB.foo.b == true, "g.containerB.foo.b == true");
	}

	static void CHECK(boolean r, String msg) {

		if (!r)
			throw new RuntimeException(msg == null ? "" : "failed: " + msg);
	}
}
3 楼 polygoncell 2008-04-15  
yujiang 写道
Guice是强类型的IOC,这个看看Guice的Key就应该知道了.

A Key uniquely identifies each binding. The key consists of a type which the client depends on and an optional annotation. You can use an annotation to differentiate multiple bindings to the same type. The key's type and annotation correspond to the type and annotation at a point of injection.

1.这个问题在Guice下估计只能这样了(Spring的IOC要解决这个问题也得一一列举),
不清楚你的动态绑定是什么意思,可以看看Binder 和 Provider
2.你从任意对象中选择一个吗?如果是的话可以用Module机制直接bind(当然注解是少不了的)
3.不明白什么意思
4.大不了直接用注入Provider,什么时候要用再取得
5.看 http://docs.google.com/View?docid=dd2fhx4z_5df5hw8 的 [Injecting Constant Values]


PS:你的这些问题Guice的文档中其实都可以找到解决方法,Guice的文档还是比较可以的.


先谢谢回答我的问题。

1. 我主要是想问如何在runtime注入不同的实例。比方说有两个Foo实例:
Foo foo1 -> Foo(true, true)
Foo foo2 -> Foo(false, false)

然后我在程序中不同的地方获得两个FooContainer对象,如何实现在一个FooContainer对象中注入foo1,而在另外一个FooContainer对象里面注入foo2?
2. 没明白你的解释,什么注解? @Name?
5. 我举的这个例子里String也是需要动态注入的,不是constant。例如:
 public class FooContainer {
    @inject
    private Foo foo1;
} 

我希望在FooContainer里注入一个Foo,但是Foo里的String只有在runtime才能确定,用Guice怎么处理?
2 楼 yujiang 2008-04-15  
Guice是强类型的IOC,这个看看Guice的Key就应该知道了.

A Key uniquely identifies each binding. The key consists of a type which the client depends on and an optional annotation. You can use an annotation to differentiate multiple bindings to the same type. The key's type and annotation correspond to the type and annotation at a point of injection.

1.这个问题在Guice下估计只能这样了(Spring的IOC要解决这个问题也得一一列举),
不清楚你的动态绑定是什么意思,可以看看Binder 和 Provider
2.你从任意对象中选择一个吗?如果是的话可以用Module机制直接bind(当然注解是少不了的)
3.不明白什么意思
4.大不了直接用注入Provider,什么时候要用再取得
5.看 http://docs.google.com/View?docid=dd2fhx4z_5df5hw8 的 [Injecting Constant Values]


PS:你的这些问题Guice的文档中其实都可以找到解决方法,Guice的文档还是比较可以的.
1 楼 polygoncell 2008-04-15  
大家都对Guice不感兴趣?

相关推荐

    guice.jar/guice.jar

    guice.jar guice.jar guice.jar guice.jar guice.jar guice.jar guice.jar

    Guice用户中文指南

    Guice是一个专门为Java 5及后续版本设计的超轻量级依赖注入框架。它旨在简化应用程序组件之间的依赖管理,并提供了一个更为简洁、灵活的方式来处理对象间的耦合关系。Guice的设计目标是使开发人员能够更轻松地创建可...

    基于guice的简单项目

    在这个项目中,我们可能会看到以下几个关键组件: 1. **Module**: Guice模块定义了依赖关系和绑定规则。开发者可以创建自定义的Module类,然后在其中声明类的实例化方式。例如,我们可以创建一个`HelloWorldModule`...

    google Guice 1.0 用户指南 中文

    Guice 的优越性体现在以下几个方面: 1. 易于测试:使用 Guice,我们可以非常容易地进行单元测试。我们可以使用 Guice 来注入 Mock 对象,以便测试 Client 对象的行为。 2. 灵活性:Guice 可以帮助我们更好地管理...

    google guice 3.0源码

    在Guice 3.0源码中,我们可以深入学习以下几个关键知识点: 1. **依赖注入(Dependency Injection)**:Guice的核心概念是依赖注入,它允许我们声明所需的服务或对象,而无需在代码中硬编码创建这些对象的方式。这...

    guice-3.0.rar

    Guice-3.0是Guice的一个版本,包含了核心库guice-3.0.jar,以及与Spring和Struts2集成的扩展库guice-spring-3.0.jar和guice-struts2-plugin-3.0.jar。 1. **Guice核心概念**: - **依赖注入**:Guice的核心机制,...

    Guice 中文文档 例子

    Guice 是一个强大的依赖注入框架,它简化了 Java 应用程序中的对象创建和管理,提高了代码的可测试性和可维护性。通过中文文档和示例,开发者可以更轻松地学习和运用 Guice,以实现更优雅、可扩展的代码结构。在实践...

    Google Guice: Agile Lightweight Dependency Injection Framework

    Guice的设计目标是提供一个既强大又简单的解决方案,以解决复杂的应用程序架构问题。 - **特点**: - **简单性**:Guice的使用非常简单直观,几乎不需要编写任何配置文件。 - **高性能**:由于其简洁的设计,...

    初试Guice测试文件

    在提供的文件中,我们可以看到几个关键的类,如`Test.java`、`MyModule.java`、`Client.java`、`MyService01.java`、`Service01Impl.java`、`MyServiceImpl.java`和`MyService.java`,它们展示了Guice如何工作。...

    guice超轻量级依赖注入

    Guice,全称为Google Guice,是一款由...通过合理使用Guice,开发者可以专注于业务逻辑,而无需关心对象的创建和依赖关系的管理。在实际开发中,了解和掌握Guice的这些特性,将有助于提升代码质量,降低维护成本。

    shiro,guice集成

    接下来,可以通过创建一个 Guice Injector 并从中获取 SecurityManager 实例来使用这个模块: ```java Injector injector = Guice.createInjector(new MyShiroModule()); SecurityManager securityManager = ...

    Java on Guice

    Guice是Google推出的一个轻量级的Java依赖注入框架,其主要功能是自动管理对象之间的依赖关系。它简化了开发过程,使开发者能够更加专注于业务逻辑而非容器配置。Guice的核心特性包括: - **依赖注入**:通过将对象...

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

    赠送jar包:guice-4.0.jar; 赠送原API文档:guice-4.0-javadoc.jar; 赠送源代码:guice-4.0-sources.jar; 赠送Maven依赖信息文件:guice-4.0.pom; 包含翻译后的API文档:guice-4.0-javadoc-API文档-中文(简体)版...

    初试Guice(转)

    3. **类型安全**:Guice在编译时就能检测到错误的依赖配置,减少了运行时可能出现的问题。 4. **生命周期管理**:Guice支持多种对象生命周期策略,如单例(`@Singleton`)、原型(每次请求创建新实例)等。 5. **...

    google-guice用户手册

    针对这些问题,Guice 提供了一种简洁而强大的解决方案,它不仅减少了代码重复,还提高了代码的可测试性和可扩展性。 #### 三、Guice 的优势 - **易用性**:Guice 的设计非常直观,开发者可以快速上手。 - **单元...

    Google Guice需要的jar

    Google Guice是一个轻量级的依赖注入框架,由Google开发并维护,主要用于简化Java应用程序的构建和管理。依赖注入(Dependency Injection,简称DI)是一种设计模式,它可以帮助开发者减少代码间的耦合,提高代码的可...

    guice入门学习资料

    guice 学习资料,快速掌握guice的编程技巧以及了解其机制。

    google guice基础例子

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

Global site tag (gtag.js) - Google Analytics