使用Facade图层,服务图层和Dao图层建立RESTful web-serice。 尝试记录所有类的方法的所有调用,用注释@Log
标记@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
}
这是方面代码:
public class LoggingAspect {
@Around("@target(Log)")
public Object log(ProceedingJoinPoint pjp) throws Throwable {
log.debug("Start " + pjp.getSignature().getName());
Object result = pjp.proceed();
log.debug("End " + pjp.getSignature().getName());
return result;
}
}
Facade,Service和Dao标有@Log。 一些例子:
public Obj Facade.createObj(String name){ //1
return service.createObj(name);
}
public Obj Service.createObj(String name){ //2
return dao.createObj(name);
}
public Obj Dao.createObj(String name){ //3
Long idOfCreatedObj = /*code that creates an object and returns it's ID*/;
return loadObjById(idOfCreatedObj); /* load the created object by id */
}
public Obj Dao.loadObjById(Long id){ //4
return /* code that loads the object by it's id */;
}
在此示例中,方法1,2,3成功记录。但是不会记录嵌套的dao方法(loadObjById)。
为什么?
P.S。在spring-config.xml中有
<aop:aspectj-autoproxy proxy-target-class="true"/>
答案 0 :(得分:2)
问题是自我调用(this.methodcall()
)绕过Spring创建的动态/ cglib代理来处理交叉问题。
修复要么使用完整的Aspectj(编译时间或加载时间编织),要么通过获取代理来进行调用(而不是联合this.methodCall()
,使用proxy.methodCall()
您可以通过这种方式获取代理:
<aop:aspectj-autoproxy expose-proxy="true"/>
在您的代码中:AopContext.currentProxy()
会为您提供代理的引用。如果您有兴趣,请参阅以下一篇博客文章 - http://www.java-allandsundry.com/2012/07/reference-to-dynamic-proxy-in-proxied.html