Guice2.0的变化——第一部分 新的特性(上)

Guice2 有望于本月发布,但是它并不向下兼容 。很容易让人联想到 Python Python3000 的故事。文章分两部分:“新的特性”和“从 Guice1.0 迁徙到 2.0 ” ,先睹为快吧。

 

第一部分 新的特性

 

 

Small Features

 

l          Binder.getProvider AbstractModule.requireBinding 允许 module 使用声明式的方式,允许依赖于别的 Module

l          Binder.requestInjection 允许 module 为注册的实例在注入创建时 (Injector-creation time) 进行注入。

l          Providers.of() 方法永远保证返回相同的实例,这一点对测试来说很管用。

l          Scopes.NO_SCOPE 允许显示的设置一个“无作用域”。

l          Matcher.inSubpackage 用于匹配所有指定包下以及其子包下的所有 classes

l          Types 工具类 ( 改用泛型写了 ) 用于创建一个泛型的具体实现。( Guice 的泛型和标注真是用到出神入化的地步了)

l          AbstractModule.requireBinding 允许 module 编程方式的实现依赖。

 

 

Provider Methods

 

创建自定义的 Providers 不需要任何 boilerplate( 模板 ) 。在任意的 module 中,用 @Providers 标注来这样定义一个方法:

 

public class PaymentsModule extends AbstractModule {
	public void configure() {

	}

	@Provides
	@Singleton
	PaymentService providePaymentService(CustomerDb database) {
		DatabasePaymentService result = new DatabasePaymentService();
		result.setDatabase(database);
		result.setReplicationLevel(5);
		return result;
	}
}

 

 

在该方法 providePaymentService 中的所有参数都会被自动注入。当然,你还可配合使用 scoping annotation ,咱们这里用的就是 @Singleton 。最后方法返回的类型也就是咱们要绑定的类型。如果你期望方法返回时返回在一个 annotation 上,可以使用 @Named 来创建这样一个 annotated 类型。

当我看到这里的时候,我把我的理解说出来和大伙分享分享。通常来说,我们会在 Action 中像这样注入一些 Service

public class PaymentAction {

	public static final String SUCCESS = "success";

	@Inject
	private PaymentService paymentService;

	public String execute() {
		paymentService.execute();
		return SUCCESS;
	}
}
 

 

很好,代码简单明了。但是如果这个“ PaymentService ”在使用之前,还需要注入别的东西的话 ( 比如说 DateSourceConstant 设置等 ) ,那么以往的做法就是在 PaymentService 中继续使用 @Inject 。不过,既然叫 Guice2.0 ,总得弄点新花样吧。这样 @Provides 就来了。它允许你的“ PaymentService ”在创建 module 的时候,将所需要的参数注入进去,进行相应初始化 ( 调用 providePaymentService 方法 ) ,最后再返回给你一个你真正想要的 paymentService 对象;如果你返回的是一个 annotation ,那么也没问题:

public class PaymentAction {

	public static final String SUCCESS = "success";

	@Inject
	Named foo;

	public String execute() {
		System.out.println(foo.getClass().toString() + " " + foo.value());
		return SUCCESS;
	}
}

 

 

相应的 PaymentsModule 中加入:

 

public class PaymentsModule extends AbstractModule {

	@Named("foo")
	private String foo;

	...

	@Provides
	@Singleton
	Named provideNamed() throws Exception {
		Named name = getClass().getDeclaredField("foo").getAnnotation(
				Named.class);
		return name;
	}
}

 

 

我想看到这里,大家应该明白了吧。继续 ~~~

 

 

Binding Overrides

Module functionalTestModule = Modules.override(new ProductionModule()).with(newOverridesModule());

 

 

顾名思义,允许用新的 module 来复盖原有的 module 。这样的好处在于,你可以开发测试中使用一套 test module ,而在正式的产品中使用另一套 production module 。

 

 

Multibindings, MapBindings

 

这也是 Guice2 新加入的,先将元素绑定在 SetMap 中,然后注入整个 Collection 。如果多个 module 都有同样的 Collection ,那么 Guice 会帮你合并。

public class SnacksModule extends AbstractModule {
  protected void configure() {
    MapBinder<String, Snack> mapBinder
        = MapBinder.newMapBinder(binder(), String.class, Snack.class);
    mapBinder.addBinding("twix").toInstance(new Twix());
    mapBinder.addBinding("snickers").toProvider(SnickersProvider.class);
    mapBinder.addBinding("skittles").to(Skittles.class);
  }
}
 

 

Private Modules

 

PrivateModules 用于创建并不需要对外可见的绑定对象。当然,这样会使得封装变得更加简单,还避免了冲突。

作者没有写关于 PrivateModules 的内容,有可能还没有更新完吧。我们就简单看一个例子:

public class FooBarBazModule extends PrivateModule {
   protected void configurePrivateBindings() {
     bind(Foo.class).to(RealFoo.class);
     expose(Foo.class); //expose方法用于向外部暴露内部的绑定Foo

     install(new TransactionalBarModule()); //install方法允许将本PrivateModule模块嵌入到TransactionalBarModule模块中去。
     expose(Bar.class).annotatedWith(Transactional.class); //expose方法用于向外部暴露内部的绑定Bar,并令其标注为Transactional

     bind(SomeImplementationDetail.class);
     install(new MoreImplementationDetailsModule());
   }

	//向外部暴露的方法
   @Provides @Exposed
   public Baz provideBaz() {
     return new SuperBaz();
   }
 }
 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值