这是我第一次使用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");
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
弹簧配置
<aop:aspectj-autoproxy />
<bean id="myAspect" class="com.pkg.MyAspect" />
<bean id="invalidSessionIdHandler" class="com.pkg.InvalidSessionIdHandler" />
Run Code Online (Sandbox Code Playgroud)
我的意图是当我依次myAspect.method1()调用时调用method2,如果method2抛出InvalidSessionIdException,则仅method2应重试。但是上面的代码似乎没有任何作用。从method2抛出异常后,它立即返回。但是,如果我穿上衣服@RetryOnInvalidSessionId,method1那么整体将method1被重试。
为了学习我一直method2是公开的,但实际上我希望是这样private。我在这里不知道如何重试私有方法。
任何的意见都将会有帮助。
谢谢
您当前的设置无法做到这一点。借助Spring的AOP功能,您的类InvalidSessionIdHandler将作为Bean创建,然后扫描注释/方法签名/等。与您的MyAspect班级有关。它将找到method2()并因此创建一个包装已创建的bean的代理。代理将根据您的建议执行操作。
Spring将在需要的地方注入这个(代理)bean。例如:
public class MyClass {
@Autowired
private MyAspect aspect;
public void callMethod2() {
aspect.method2();
}
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,MyClass对象具有对代理的引用。当它调用时aspect.method2(),将执行添加的行为。
但是,在您的代码中,您希望method2()在method1()
public void method1() throws AsyncApiException {
System.out.println("In Method1. calling method 2");
method2();
}
Run Code Online (Sandbox Code Playgroud)
这是你MyAspect班上的 从技术上讲,这里发生了什么是method2()获取调用上this的this.method2()。this是对实际对象的引用,而不是对代理的引用。因此,它将不会执行任何其他行为。
该AOP Spring文档更详细地解释这一点。
这里的解决方法是重构,使其method2()位于另一个类/对象中,或者从外部调用它,即。不是来自method1()。
| 归档时间: |
|
| 查看次数: |
7854 次 |
| 最近记录: |