gpt4 book ai didi

java - 创建现有对象的@UnitOfWork 感知代理

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:05:35 25 4
gpt4 key购买 nike

我有以下类(class):

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 获得代理。

我尝试使用拦截器将这些代理提供给 Guice,但我遇到了一个问题,因为 UnitOfWorkAwareProxyFactory 只创建新实例,从不让我传递现有对象。新实例的问题是我不知道要给它的参数,因为它们是由 Guice 注入(inject)的。

如何创建现有对象的@UnitOfWork感知代理?

这是我到目前为止制作的拦截器:

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(或 Guice)为我提供了一种更简单的方法,那是什么?

最佳答案

从 Dropwizard 1.1 开始:(截至 2016 年 8 月 10 日尚未发布)

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();
}
}
}
}

关于java - 创建现有对象的@UnitOfWork 感知代理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38261787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com