我有aop配置如下
aop:config>
<aop:aspect id="Intercepter" ref="aspect1">
<aop:around pointcut="execution(* *..*ServiceImpl.*(..))"
method="serviceIntercept" />
</aop:aspect>
</aop:config>
<bean id="aspect1" class=Intercepter">
</bean>
public class Intercepter
{
private String variable1;
public Intercepter()
{
}
public Object serviceIntercept(ProceedingJoinPoint pjp)
throws Throwable
{
Object retVal = null;
//Method M1 set value of variable1
M1();
// call actual Method on ServiceImpl
retVal = pjp.proceed();
}
public class AServiceImpl {
Method1();
Method1(){
call Method2 on BServiceImpl from AServiceImpl
BServiceImpl.Method2()
}
}
public class BServiceImpl {
Method2();
}
Main(){
// call AServiceImpl assuming it is single threaded.
AServiceImpl()
}
所以序列如下
1.首先从Main()调用AServiceImpl(),它被拦截,变量variable1被设置为variable1 =“test”; 2.现在调用AServiceImpl上的实际方法Method1()。
3.从Method1()再次调用BServiceImpl上的Method2()。然后它被拦截。之前,variable1的值被设置为“test”,现在这次被设置为“”。所以每当它被截获时变量1的值改变了
那么,编写aop的最佳做法是什么,以便从多线程和单线程程序中获得安全性?
。在这种情况下它是单例,因为类Intercepter是单例和单线程的。所以我可以看到问题编写方面为单例。类似的问题可能在多线程程序中出现。可能会将方面类编写为不可变类或替换单身与原型可以解释我的理解。但是,我希望获得更深入的想法和信息,以及人们在他们的progaram中使用的不同方法的解决方案。
答案 0 :(得分:0)
在多线程程序中保持单例状态的最简单方法是使用ThreadLocal
变量。
在您的情况下,您必须将String variable1
替换为ThreadLocal<String> variable1
。
使用ThreadLocal
时,您必须在不再使用时清除值。一个好地方通常是finally
子句,如:
try {
variable1.set(...)
pjp.proceed();
} finally {
variable1.remove();
}