如何调试 Guice class/method 拦截器?
How to debug Guice class/method interceptors?
我正在尝试使用 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);
}
问题:
为什么会这样?
我如何调试它以找出它发生的原因?有什么方法可以将日志记录添加到 class/method 匹配器吗?
这里有几个问题:
- Java 无法创建最终 classes 或方法的代理。在这种情况下,Guice 应该给出错误或警告,但由于某种原因,并没有。
- 注释不在 class 上,而是在超级 class 上。标准方法匹配器只考虑 class 的方法。如果你想要不同的行为,你需要这个匹配器:
要调试 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;
}
}
我正在尝试使用 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);
}
问题:
为什么会这样?
我如何调试它以找出它发生的原因?有什么方法可以将日志记录添加到 class/method 匹配器吗?
这里有几个问题:
- Java 无法创建最终 classes 或方法的代理。在这种情况下,Guice 应该给出错误或警告,但由于某种原因,并没有。
- 注释不在 class 上,而是在超级 class 上。标准方法匹配器只考虑 class 的方法。如果你想要不同的行为,你需要这个匹配器:
要调试 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;
}
}