这是我第一次使用AOP,所以这可能是一个非常无聊的问题。
public class MyAspect implements AspectI {
public void method1() throws AsyncApiException {
System.out.println("In Method1. calling method 2");
method2();
}
@RetryOnInvalidSessionId
public void method2() throws AsyncApiException {
System.out.println("In Method2, throwing exception");
throw new AsyncApiException("method2", AsyncExceptionCode.InvalidSessionId);
}
public void login() {
System.out.println("Logging");
}
InvalidSessionHandler看起来像这样。
@Aspect
public class InvalidSessionIdHandler implements Ordered {
@Around("@annotation(com.pkg.RetryOnInvalidSessionId)")
public void reLoginAll(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Hijacked call: " + joinPoint.getSignature().getName() + " Proceeding");
try {
joinPoint.proceed();
} catch (Throwable e) {
if (e instanceof AsyncApiException) {
AsyncApiException ae = (AsyncApiException) e;
if (ae.getExceptionCode() == AsyncExceptionCode.InvalidSessionId) {
System.out.println("invalid session id. relogin");
AspectI myAspect = (AspectI) joinPoint.getTarget();
myAspect.login();
System.out.println("Login done. Proceeding again now");
joinPoint.proceed();
}
}
}
}
@Override
public int getOrder() {
return 1;
}
}
Spring配置
<aop:aspectj-autoproxy />
<bean id="myAspect" class="com.pkg.MyAspect" />
<bean id="invalidSessionIdHandler" class="com.pkg.InvalidSessionIdHandler" />
我的意图是当我致电myAspect.method1()
时,如果method2
抛出method2
异常,那么只有InvalidSessionId
才会调用method2
重试。但上面的代码似乎没有做任何事情。它只是在从method2抛出异常后立即返回。但是,如果我将@RetryOnInvalidSessionId
放在method1
上,则会重试整个method1
。
为了学习我保持method2
是公开的,但实际上我希望它是private
。我在这里没有线索,如何重试私人方法。
任何建议都会有所帮助。
由于
答案 0 :(得分:5)
目前的设置无法做到这一点。使用Spring的AOP功能,您的类InvalidSessionIdHandler
将被创建为bean,然后扫描注释/方法签名/等。与您的MyAspect
课程相关。它会找到method2()
,因此创建一个包装已经创建的bean的代理。代理将根据您的建议行事。
Spring会在你需要的地方注入这个(代理)bean。例如:
public class MyClass {
@Autowired
private MyAspect aspect;
public void callMethod2() {
aspect.method2();
}
}
在这种情况下,MyClass
对象具有对代理的引用。当它调用aspect.method2()
时,将执行添加的行为。
但是,在您的代码中,您希望在method2()
method1()
public void method1() throws AsyncApiException {
System.out.println("In Method1. calling method 2");
method2();
}
位于MyAspect
班级内。从技术上讲,这里发生的事情method2()
被this
称为this.method2()
。 this
是对实际对象的引用,而不是代理。因此,它不会执行任何其他行为。
AOP Spring documentation更详细地解释了这一点。
这里的解决方法是重构,以便method2()
在另一个类/对象中或从外部调用它,即。不是来自method1()
。