如何调试Guice类/方法拦截器?

问题描述

我正在尝试使用guice-persist,但无法在简单的测试用例中使用它。这是一个一般的请求处理程序,正在从调度程序中调用:

public abstract class TransactionAwareRequestHandler<T> extends SyncRequestHandler<T> {

    @Transactional // Guice should make sure I get a transaction here
    public final Object handleRequest(T request) {
        return handleRequestWithTx(request);
    }

    public abstract Object handleRequestWithTx(T request);
}

我的测试处理程序是:

public static class TestHandler extends TransactionAwareRequestHandler {
    @Override
    public Object handleRequestWithTx(Object request) {
        SessionFactory sessionFactory = injector.getProvider(SessionFactory.class).get();
        assertTrue(sessionFactory.getCurrentSession().getTransaction().isActive()); // <<<--- Fails here!
        return null;
    }
}

向导设置:

    injector = Guice.createInjector(
        new HibernatePersistModule()
    );

这将为所有用@Transactional注释的类和方法添加一个绑定拦截器。

测试用例:

@Test
public void shouldRunInTransaction() throws RequestHandlerException {
    TestHandler handler = injector.getInstance(TestHandler.class);
    
    // I'm not getting a proxy here! Why???
    assertTrue("Expected proxy: " + handler.getClass(),Proxy.isProxyClass(handler.getClass()));
    
    handler.handleRequest(null);
}

问题:

为什么会这样?

我该如何调试它以查明原因呢?有什么方法可以将日志添加到类/方法匹配器中?

解决方法

这里有几个问题:

  1. Java无法创建最终类或方法的代理。在这种情况下,Guice应该给出错误或警告,但由于某些原因,不会。
  2. 注释不在类上,而是在超类上。标准方法匹配器仅考虑类的方法。如果您想要其他行为,则需要以下匹配器:https://stackoverflow.com/a/61674578/34088

要调试Guice的操作,请将匹配器包装在进行日志记录的一个中:

import java.util.Objects;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.matcher.AbstractMatcher;
import com.google.inject.matcher.Matcher;

public class MatcherLogger<T> extends AbstractMatcher<T> {

    private final Matcher<T> delegate;
    private final Logger log;
    
    public MatcherLogger(Matcher<T> delegate) {
        this(delegate,LoggerFactory.getLogger(MatcherLogger.class));
    }

    public MatcherLogger(Matcher<T> delegate,Logger log) {
        this.delegate = Objects.requireNonNull(delegate);
        this.log = Objects.requireNonNull(log);
    }
    
    @Override
    public boolean matches(T t) {
        boolean result = delegate.matches(t);
        log.debug("matches {} for {}",result,t);
        return result;
    }
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...