Guice 简介
Guice是由Google开发的轻量级的依赖注入的工具。 也许大家都了解Spring的依赖注入,两者的功能基本相同。依赖注入在我们的工程项中最主要的功能就是解耦,并能够管理对象的生命周期。
Guice 基本使用
/**
* 基于注解的bind接口
*/
@ImplementedBy(GuiceService.DefaultGuiceService.class)
public interface GuiceService {
public String info();
class DefaultGuiceService implements GuiceService {
@Override
public String info() {
return "this is a test";
}
}
}
/**
*
* 注入类
*
*/
public class Client {
@Inject
private GuiceService guiceService; //@ImplementedBy(GuiceService.DefaultGuiceService.class) 注解表明接口和实现的关系
public void print() {
System.out.println("client :" + guiceService.info());
}
}
/**
* 调用
*
*/
public class Main {
public static void main(String[] args) {
Injector injector = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
// bind(GuiceService.class).to(GuiceService.DefaultGuiceService.class); //配置中绑定
}
});
Client client = injector.getInstance(Client.class);
client.print();
}
}
接口与实现类的绑定
-
bind(A.class).toInstance(new AImpl())
将A接口绑定到一个对象的实例; 这表明这个接口是单例?
-
bind(A.class).to(AImpl.class)
指明接口的实现类
-
@ImplementedBy
接口的注解,标记此接口是哪个实现类的接口
-
Provider
更灵活的一种绑定方式,比如可以绑定代理类
-
annotatedWith(AA.class)
当一个接口有多个实现的时候,使用自定义annotation区分
以上四点都是指明接口和实现类的关系,将两者绑定,在使用的时候,则直接使用接口对象即可。如果一个类不是接口的实现类,则在系统中直接使用即可
Provider
bind(GuiceService.class).toProvider(new Provider<GuiceService>() {
@Override
public GuiceService get() {
return ProxyFactory.create(GuiceService.class); // 绑定到代理类
}
});
这里Provider就对使用者开放了更多的权限,可以在每次获取对象的时候,做一些额外的事情。这需要在具体使用中,自己发挥想象
Scope
一个对象的作用域有两种方式定义,一种是基于注解,一种是在Module中指定
-
@Singleton
单例
-
无注解
每次都会生成新的对象
-
自定义Scope
比如requestScope,SessionScope,将一个对象的生命周期限制在一次请求,或者一个会话之中
-
in(Scopes.SINGLETON) or in(Class-Annotation)
Module中指定
-
自定义Scope
/**
*
* Scope 的实现
* 作用: 被VineScope定义的对象,它的生命周期在enter 和 exit之间。 在enter之后,对象被存储在ThreadLocal之中,exit之后则被删除。在两者之间的操作中,都可以获取到这个对象
*
*/
public class VineScope implements Scope {
private static VineScope vineScope = new VineScope();
public static VineScope getScope() {
return vineScope;
}
private final ThreadLocal<Map<Key<?>, Object>> scopedObjectMapHolder = new ThreadLocal<>();
private VineScope() {}
public void enter() {
checkState(scopedObjectMapHolder.get() == null, "A vine scope block is already in progress");
scopedObjectMapHolder.set(new HashMap<>());
}
public void exit() {
checkState(scopedObjectMapHolder.get() != null, "No vine scope block in progress");
scopedObjectMapHolder.remove();
}
public <T> void seed(Key<T> key, T value) {
Map<Key<?>, Object> scopedObjectMap = getScopedObjectMap(key);
checkState(!scopedObjectMap.containsKey(key), "A value for key [%s] was already seeded in this vine scope, " +
"old value: [%s], new value: [%s]", key, scopedObjectMap.get(key), value);
scopedObjectMap.put(key, value);
}
public <T> void seed(Class<T> clazz, T value) {
seed(Key.get(clazz), value);
}
@Override
public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
return () -> {
Map<Key<?>, Object> scopedObjectMap = getScopedObjectMap(key);
@SuppressWarnings("unchecked")
T current = (T) scopedObjectMap.get(key);
if (current == null && !scopedObjectMap.containsKey(key)) {
current = unscoped.get();
if (Scopes.isCircularProxy(current)) {
return current;
}
scopedObjectMap.put(key, current);
}
return current;
};
}
private <T> Map<Key<?>, Object> getScopedObjectMap(Key<T> key) {
Map<Key<?>, Object> scopedObjectMap = scopedObjectMapHolder.get();
if (scopedObjectMap == null) {
throw new OutOfScopeException("Cannot access " + key
+ " outside of a vine scoping block");
}
return scopedObjectMap;
}
}
/**
* 将VineScope绑定到一个注解上,在Module中定义
*
*/
// Scope
VineScope scope = VineScope.getScope();
bindScope(VineScoped.class, scope);
bind(VineScope.class).toInstance(scope);