Eu comecei a estudar um pouco o Guice, que é um framework da google de injeção de dependência. Estava fazendo uns testes e queria ter uma forma de que o Guice me retornasse sempre a mesma instância quando solicitar um objeto na mesma thread, algo como se feito com esse Factory:
public class ServiceFactory {
private static ThreadLocal<Service> tl = new ThreadLocal<Service>();
public static Service get() {
Service t = tl.get();
if (t == null) {
t = new ServiceImpl();
tl.set(t);
}
return t;
}
}
Porém não achei um scope para isso (na real procurei bem pouco). Resolvi, até para aprendizado criar um novo scope para que seja ThreadLocal, até que deu certo, eis o resultado: import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.Scope;
...
class LocalThreadScope implements Scope {
public <T> Provider<T> scope(Key<T> key, final Provider<T> provider) {
return new Provider<T>() {
ThreadLocal<T> tl = new ThreadLocal<T>();
public T get() {
T t = tl.get();
if (t == null) {
t = provider.get();
tl.set(t);
}
return t;
}
};
}
@Override
public String toString() {
return "ThreadLocalScope";
}
}
Usando-se esse Scope para fazer o bind, o Guice ira criar um novo objeto para cada thread diferente. Exemplo: public interface Service {
void go();
}
public class ServiceImpl implements Service {
public void go() {
System.out.println(this + " - " + Thread.currentThread());
}
}
public class MyModule implements Module {
public void configure(Binder binder) {
binder.bind(Service.class).to(ServiceImpl.class).in(
new LocalThreadScope());
}
}
public class Main {
public static void main(String[] args) {
final Injector inj = Guice.createInjector(new MyModule());
Service s = inj.getInstance(Service.class);
s.go();
s = inj.getInstance(Service.class);
s.go();
Runnable r1 = new Runnable() {
public void run() {
Service s = inj.getInstance(Service.class);
s.go();
}
};
new Thread(r1).start();
}
}
Nenhum comentário:
Postar um comentário