我有一个很明显的问题,虽然我不知道如何解决它。 我有2个班,其中1个是拦截器。
@Stateless
@Interceptors(AutoId.class)
public class TestClass {
private static final Logger LOG = Logger.getLogger(RepositoryBean.class.getName());
public void executeUpdate(){
int k=0;
for (int i = 0; i < 1000000; i++) {
for (int j = 0; j < 100000; j++) {
for (int r = 0; r < 1000000; r++) {
k = 1;
}
}
}
getLogger().log(Level.INFO, "Current time some time ago was "+AutoId.MyTime/1000);
}
private Logger getLogger() {
return Logger.getLogger(getClass().getCanonicalName());
}}
这里是Interceptor类:
public class AutoId {
public static Long MyTime;
@AroundInvoke
public Object addLog(InvocationContext context) throws Exception {
MyTime= System.currentTimeMillis();
return context.proceed();
}
}
一个明显的问题是,如果我运行这个应用程序(当它部署在glassfish服务器上时),然后在几秒钟内运行它的另一个副本,它将用新的时间重写MyTime变量,并且结果,两个程序将同时打印。 一个显而易见的解决方案是在executeUpdate中创建一个变量来保存MyTime的值,但这对我正在处理的实际项目来说并不好。
有人告诉我,我可能想用ContextResolver和@Context做点什么。 虽然如何解决这个问题? 感谢。
修改 我找到了一个解决方案,虽然我不认为这是最好的
public class AutoId {
private static Long[] MyTime = new Long[1000];
@AroundInvoke
public Object addLog(InvocationContext context) throws Exception {
MyTime[(int)Thread.currentThread().getId()]= System.currentTimeMillis();
return context.proceed();
}
public static Long MyTime(){
return MyTime[(int)Thread.currentThread().getId()];
}
}
命名数组的方式与过程允许最小化主类中的代码更改只能通过在AutoId.MyTime - &gt;之后添加()来实现。 AutoId.MyTime()
这仍然不是最好的主意,虽然它不会导致重写变量。
EDIT2 请不要介意executeUpdate()过程中的所有代码。它只是以某种方式编写完成工作,因此我可以再执行一次并打印出AutoId.MyTime。这个变量的值是唯一重要的。
另外很明显,如果我没有使用Interceptor,只是在类中创建了一个AutoId变量,在任何其他程序(这就是拦截器)之前调用它,那个错误就不会出现,因为每个程序副本都会有很容易拥有自己的身份 - 但这不是选择。在执行任何程序之前,需要使用拦截器进行自动化。希望能解释我之前没有告诉过的所有内容:)
答案 0 :(得分:0)
您可以使用@Produces
创建记录器,然后使用@Inject
将您的记录器注入您的类和拦截器。这样你就可以记录不同的时间。