我需要审计ejb bean的调用。说审计,我指的是写信息,如当前日志记录的用户,方法名称,数据库的附加描述。我决定用CDI装饰器来做:
@Decorator
public class AccountServiceBeanDecorator implements AccountService {
@Inject
@Delegate
@Any
AccountService accountService;
@EJB
private AuditService auditService;
@Override
public Account createAccount(Account account) {
auditService.saveAudit("Method: createAccount", currentUser, "Creating account by admin");
return accountService.createAccount(account);
}
}还有被装饰的班级:
@Stateless
public class AccountServiceBean implements AccountService {
@Override
public Account createAccount(Account account) {
...
}
}现在,如果我从另一个ejb无状态bean调用AccountService,那么事务会发生什么情况呢?
@Stateless
public ApplicationFacadeBean implements ApplicationFacade {
@EJB
private AccountService accountService;
@Override
public Account createAccount(Account account) {
return accountService.createAccount(account);
}
}我想记录装饰器(AccountServiceBeanDecorator)和装饰类(AccountServiceBean)中的事务状态,所以我在这两个类中注入了TransactionSynchronizationRegistry作为资源:
@Decorator
public class AccountServiceBeanDecorator implements AccountService {
@Inject
@Delegate
@Any
AccountService accountService;
@EJB
private AuditService auditService;
@Resource
private TransactionSynchronizationRegistry reg;
@Override
public Account createAccount(Account account) {
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
log.info("tx ({}): {}", new Object[] {reg.getTransactionStatus(), reg.getTransactionKey()});
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
auditService.saveAudit("Method: createAccount", currentUser, "Creating account by admin");
return accountService.createAccount(account);
}
}和
@Stateless
public class AccountServiceBean implements AccountService {
@Resource
private TransactionSynchronizationRegistry reg;
@Override
public Account createAccount(Account account) {
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
log.info("tx ({}): {}", new Object[] {reg.getTransactionStatus(), reg.getTransactionKey()});
log.info("%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%");
...
}
}我收到了奇怪的行为:
有人能给我解释一下吗?Wheter类在与ApplicationFacade相同的事务中被调用?
谢谢
发布于 2015-01-22 20:12:17
first: i不会将ejbs与cdi拦截器混合。ejbs将其用于拦截器实现。
第二步:拦截器在与拦截器所在的事务相同的事务中执行。
可能的解决方案:
这将从拦截器所在的ejb当前事务中创建一个新事务。
--我知道我的英语不是很好。但我希望你明白我认为什么应该有效。如果我有时间,我在github上做个例子.
发布于 2014-04-20 02:13:39
嗯..。你用的是什么容器?通常,我不会怀疑CDI装饰师在EJB上工作.我想不出在JEE规范中我遇到的任何东西都能提供证据。
但是,面对你的问题,我是用拦截器,而不是装饰器。这些都得到EJB规范的支持.总之,这是我的代码,在您的情况下,您需要从上下文中获取变量:
import java.lang.reflect.Method;
import javax.inject.Inject;
import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
public class InvocationCountInterceptor {
@Inject
private InvocationCounter counter;
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
Object returnValue = ctx.proceed();
Class<? extends Object> className = ctx.getTarget().getClass();
Method methodName = ctx.getMethod();
counter.incrementCounter(className, methodName);
return returnValue;
}
}然后,不管您想要审计哪个EJB或EJB方法,我只是添加了以下内容:@Interceptors(InvocationCountInterceptor.class)
https://stackoverflow.com/questions/23120113
复制相似问题