google Guice的特殊用法

这几天看源码发现几个地方记录一下 ,过两天看源码或者上maillist问个究竟

第一 如何取得隐藏的注入实例

先定义几个辅助类

[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
public interface TESTA {

public String getName();

}
public class TESTAA implements TESTA {
@Override
public String getName() {
// TODO Auto-generated method stub
return "A";
}
}
public class TESTAB implements TESTA {
@Override
public String getName() {
// TODO Auto-generated method stub
return "B";
}
}
public interface TESTA {

public String getName();

}
public class TESTAA implements TESTA {
@Override
public String getName() {
// TODO Auto-generated method stub
return "A";
}
}
public class TESTAB implements TESTA {
@Override
public String getName() {
// TODO Auto-generated method stub
return "B";
}
}
[/ccn]
写测试代码

[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
public class TestGuiceMain {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}

@Test
public void testRun(){
final List list = Lists.newArrayList();
list.add(new TESTAA());
list.add(new TESTAB());
Module ServiceModule = new AbstractModule() {
protected void configure() {
//业务绑定
bind( Key.get( new TypeLiteral>() {}, UniqueAnnotations.create() ) ).toInstance(list);
}
};

// 创建Injector
Injector injector = Guice.createInjector(Stage.DEVELOPMENT, ServiceModule);

Key> key = Key.get(new TypeLiteral>() {});
//这样是拿不到的 就更别说在业务代码里使用annotation来inject了
List a = injector.getInstance(key);
}
}
[/ccn]
[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
public class TestGuiceMain {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}

@Test
public void testRun(){
final List list = Lists.newArrayList();
list.add(new TESTAA());
list.add(new TESTAB());
Module ServiceModule = new AbstractModule() {
protected void configure() {
//业务绑定
bind( Key.get( new TypeLiteral>() {}, UniqueAnnotations.create() ) ).toInstance(list);
}
};

// 创建Injector
Injector injector = Guice.createInjector(Stage.DEVELOPMENT, ServiceModule);

Key> key = Key.get(new TypeLiteral>() {});
//这样是拿不到的 就更别说在业务代码里使用annotation来inject了
List a = injector.getInstance(key);
}
}
[/ccn]
那如何才能取得实例呢

[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
public class TestGuiceMain {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}

@Test
public void testRun(){
final List list = Lists.newArrayList();
list.add(new TESTAA());
list.add(new TESTAB());
Module ServiceModule = new AbstractModule() {
protected void configure() {
//业务绑定
bind( Key.get( new TypeLiteral>() {}, UniqueAnnotations.create() ) ).toInstance(list);
}
};

// 创建Injector
Injector injector = Guice.createInjector(Stage.DEVELOPMENT, ServiceModule);

Key> key = Key.get(new TypeLiteral>() {});
List instance = Lists.newArrayList();
for ( Binding entry : injector.findBindingsByType( new TypeLiteral>() { } ) ) {
@SuppressWarnings("unchecked")
Key> defsKey = (Key>) entry.getKey();
instance.addAll(injector.getInstance(defsKey));
}
}
}
[/ccn]
[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
public class TestGuiceMain {
@Before
public void setUp() throws Exception {
}
@After
public void tearDown() throws Exception {
}

@Test
public void testRun(){
final List list = Lists.newArrayList();
list.add(new TESTAA());
list.add(new TESTAB());
Module ServiceModule = new AbstractModule() {
protected void configure() {
//业务绑定
bind( Key.get( new TypeLiteral>() {}, UniqueAnnotations.create() ) ).toInstance(list);
}
};

// 创建Injector
Injector injector = Guice.createInjector(Stage.DEVELOPMENT, ServiceModule);

Key> key = Key.get(new TypeLiteral>() {});
List instance = Lists.newArrayList();
for ( Binding entry : injector.findBindingsByType( new TypeLiteral>() { } ) ) {
@SuppressWarnings("unchecked")
Key> defsKey = (Key>) entry.getKey();
instance.addAll(injector.getInstance(defsKey));
}
}
}
[/ccn]
所以不管你绑定什么Type最后都会被overload成绑定一个Key

而这个key肯定也会附着一个annotation 所有只有条件都符合的时候才会发生注入

上面的方法是在guice内部和spi使用的方法

第二 静态的注入

[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
protected void requestStaticInjection(Class... types) {
binder.requestStaticInjection(types);
}
protected void requestStaticInjection(Class... types) {
binder.requestStaticInjection(types);
}
[/ccn]
这个方法会把这个类型的静态field通过静态的方法或者构造函数进行早期绑定注入

第三 单独绑定某个类型

比如

bind(TEST.class);

对于他的作用 Dhanji R给我的回答是

用于错误检查,如果是在Stage.PRODUCTION模式下的Singleton 则会被早期实例化