问题描述
我有以下课程:
public FooDAO extends AbstractDAO<Foo> { // Dropwizard DAO
@Inject FooDAO(SessionFactory sf) { super(sf); }
public void foo() { /* use SessionFactory */ }
}
public class FooService {
private final FooDAO fooDAO; // Constructor-injected dependency
@Inject FooService (FooDAO fooDAO) { this.fooDAO = fooDAO; }
@UnitOfWork
public void foo() {
this.fooDAO.foo();
System.out.println("I went through FooService.foo()");
}
}
现在, FooService
不是资源,因此Dropwizard不了解它,也不会自动代理它。但是Dropwizard的聪明人做到了,所以我可以通过 UnitOfWorkAwareProxyFactory
来获得代理。
Now, FooService
is not a resource, so Dropwizard doesn't know about it and doesn't automagically proxy it. However the smart guys at Dropwizard made it so I can get a proxy through UnitOfWorkAwareProxyFactory
.
我尝试为这些饲料喂食用拦截器代理Guice,但我遇到了一个问题,因为 UnitOfWorkAwareProxyFactory
只会创建新实例,而永远不会让我传递现有对象。新实例的问题在于我不知道要提供的参数,因为它们是由Guice注入的。
I tried doing feeding these proxies to Guice with an interceptor, but I faced an issue because UnitOfWorkAwareProxyFactory
only ever creates new instances and never lets me pass existing objects. The thing with new instances is that I don't know the parameters to give it since they're injected by Guice.
如何创建 @UnitOfWork
知道现有对象的代理吗?
How do I create @UnitOfWork
-aware proxies of existing objects?
这是我到目前为止所做的拦截器:
Here's the interceptor I've made so far:
public class UnitOfWorkModule extends AbstractModule {
@Override protected void configure() {
UnitOfWorkInterceptor interceptor = new UnitOfWorkInterceptor();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(UnitOfWork.class), interceptor);
requestInjection(interceptor);
}
private static class UnitOfWorkInterceptor implements MethodInterceptor {
@Inject UnitOfWorkAwareProxyFactory proxyFactory;
Map<Object, Object> proxies = new IdentityHashMap<>();
@Override public Object invoke(MethodInvocation mi) throws Throwable {
Object target = proxies.computeIfAbsent(mi.getThis(), x -> createProxy(mi));
Method method = mi.getMethod();
Object[] arguments = mi.getArguments();
return method.invoke(target, arguments);
}
Object createProxy(MethodInvocation mi) {
// here, what to do? proxyFactory will only provide objects where I pass constructor arguments, but... I don't have those!
}
}
}
当然,如果Dropwizard(
Of course, if Dropwizard (or Guice) offers me a simpler way to do so, which is it?
推荐答案
从Dropwizard 1.1开始:(截至2016年8月10日尚未发布)
As from Dropwizard 1.1: (not yet released, as of August 10, 2016)
public class UnitOfWorkModule extends AbstractModule {
@Override
protected void configure() {
UnitOfWorkInterceptor interceptor = new UnitOfWorkInterceptor();
bindInterceptor(Matchers.any(), Matchers.annotatedWith(UnitOfWork.class), interceptor);
requestInjection(interceptor);
}
@Provides
@Singleton
UnitOfWorkAwareProxyFactory provideUnitOfWorkAwareProxyFactory(HibernateBundle<AlexandriaConfiguration> hibernateBundle) {
return new UnitOfWorkAwareProxyFactory(hibernateBundle);
}
private static class UnitOfWorkInterceptor implements MethodInterceptor {
@Inject
UnitOfWorkAwareProxyFactory proxyFactory;
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
UnitOfWorkAspect aspect = proxyFactory.newAspect();
try {
aspect.beforeStart(mi.getMethod().getAnnotation(UnitOfWork.class));
Object result = mi.proceed();
aspect.afterEnd();
return result;
} catch (InvocationTargetException e) {
aspect.onError();
throw e.getCause();
} catch (Exception e) {
aspect.onError();
throw e;
} finally {
aspect.onFinish();
}
}
}
}
这篇关于创建现有对象的@UnitOfWork感知代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!