Guice的scope

Guice的scope默认的有一个singleton,

所以scope大致的作用就是对于这个需要让guice管理的类型,如何注入,注入的是哪个对象

比如@Singleton就是说在需要注入的地方注入此类型的唯一实例,此jvm里的任何用到的地方都是唯一的

有人会说那Provider不就可以实现这个需要吗?

没错,但是你不得不为每一个你需要的的对象都写一个singleton模式的Provider,

所以scope就产生了, 其实他就是如何去使用Provider的一个定义,我guice的源码没有看完,但是我猜想

guice会自己为用户做的绑定产生匿名的Provider

看下面这个需求:

我们需要在所有的servlet请求里拿一个对象A,这个A的实例我希望按照我的绑定配置来注入,我可以:

bind(...).to(A.class);或者

bind().toProvider(providerA);

但是我希望他自己每次保存到request里,不需要我再繁琐的写

request.getAttribute("mya");和request.setAttribute("mya", mya);

这样的话,你只需要在你的业务类里做一个@Inject private A mya;就可以了,guice就会自己给你从request里去取,如果没有

就会调用providerA,再保存到request里,你只需要做以下绑定就可以一劳永逸了.

[ccn lang="java" tab_size="4" theme="blackboard" width="550" ]
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ScopeAnnotation
public @interface RequestScoped {}

......
public static final Scope REQUEST = new Scope() {
public Provider scope(Key key, final Provider creator) {
final String name = key.toString();
return new Provider() {
public T get() {
HttpServletRequest request = GuiceFilter.getRequest();
synchronized (request) {
@SuppressWarnings("unchecked")
T t = (T) request.getAttribute(name);
if (t == null) {
t = creator.get();
request.setAttribute(name, t);
}
return t;
}
}
public String toString() {
return String.format("%s[%s]", creator, REQUEST);
}
};
}
.......
绑定scope
bindScope(RequestScoped.class, REQUEST);
.......

@RequestScoped
class A{
......
}

@RequestScoped
class B{
......
}
//业务类
class Myservice{
......
@Inject private A a;
@Inject private B b;
......
}
[/ccn]