创建现有对象的@UnitOfWork感知代理 [英] Create @UnitOfWork-aware proxies of existing objects

查看:188
本文介绍了创建现有对象的@UnitOfWork感知代理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

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感知代理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆