先前已经讲述了绑定的一个基本流程,然后我们尝试将guice黑盒后,注入和绑定是分开的。在绑定的时候,我们可以有很多非常灵活的结构、语法和概念来需要掌握。
module是可以互相嵌套与并列的,嵌套的话可以install引入,当然还有覆盖。
eg: bind(PriceService.class).to(PriceServiceImpl.class);
eg: bind(PriceService.class).toInstance(new PriceServiceImpl());
一般我们通过测试的时候,可以在测试类后面再加入一个Module来具现化连接绑定测试。
bind(PriceService.class).to(PriceServiceImpl.class);
bind(PriceServiceImpl.class).toInstance(new PriceServiceImpl(){
@Override
public long getPrice(long orderId) {
return 766L;
}
});
@Provides Long generateSessionId(){//方式三,名字可以随便起,当且仅当仅一个类型时
return System.currentTimeMillis();
}
当然也可以传入参数,但是参数需要之前已经注入的,guice就会帮我自动注入,然而在具体的Provider的get()方法的时候依然不需要输入参数,因为guice已经帮我们做了
@Provides Long generateSessionId(PriceService priceService){
return priceService.getMoney();
}
@Provides @SessionId Long generateSessionId() {// 参考注入(一)多出一个@SesssionId
return System.currentTimeMillis();
}
或者可以给他一个名字,只关注命名和类型,匹配的时候
ServerModule.class
@Provides @Named("getCurrentTimes") Long generateSessionId() {// 方式三,名字可以随便起,当且仅当仅一个类型时
return System.currentTimeMillis();
}
SessionManager.class
@Inject
public SessionManager(@Named("getCurrentTimes") Provider SessionIdProvider) {
super();
this.SessionIdProvider = SessionIdProvider;
}
bind(new TypeLiteral>(){})
.toInstance(Arrays.asList("CNY","ENR","USD"));
当然也可以通过其他来实现,可以重新new TypeLiteral 来传入一个新的实现,也可以引入其他注释实现都可以。
eg:
bind(new TypeLiteral>(){})
.annotatedWith(Names.named("getCurrentTimes"))
.toInstance(Arrays.asList("CNY","ENR","USD"));
假设输出一个Set集合,包含币种
public class ChinaModule extends AbstractModule{
@Override
public void configure() {
// TODO suit China Yuan
Multibinder.newSetBinder(binder(), String.class)
.addBinding().toInstance("CNY");
}
}
public class GlobalModule extends AbstractModule{
@Override
public void configure() {
// TODO USD,ENY
Multibinder multibinder = Multibinder.newSetBinder(binder(), String.class);
multibinder.addBinding().toInstance("USD");
multibinder.addBinding().toInstance("ENY");
}
}
ServerModule.class
public class ServerModule extends AbstractModule {
@Override
protected void configure() {
//套入其他Module
install(new ChinaModule());
install(new GlobalModule());
bind(OrderService.class).to(OrderServerImpl.class);
bind(PaymentService.class).to(PaymentServiceImpl.class);
bind(PriceService.class).to(PriceServiceImpl.class);
}
OrderServiceImpl.class
private final Set supportedCurrenties;
@Inject
private PriceServiceImpl(Set supportedCurrenties) {
super();
this.supportedCurrenties = supportedCurrenties;
}
@Override
public Set getSupportCurrenties() {
return supportedCurrenties;
}
<2> Map绑定
MapBinder.newMapBinder(binder(), keyType, valueType)
//用法与Set相似,前者是Key,后者是Value
eg: Guice.createInjector(new ServerModule(),........... ).injectMembers(this);; //后面可以接一堆Moudule
eg: insall(new ChinaModule());//大Module下可以套小Module,一直套if you want it。。。,一般最终有一个Master存在
eg: Modules.override(new ChinaModule()).with(new GlobalModule()); //用后者覆盖前者
Module内存放了很多表达式,比如Bind().to..\install ,只是相当存放于一个map中,记录下来,它并不会被运行。整个流程花时间在于getInstance(),这是会将所有的依赖、注入建立出来。