【发布时间】:2011-08-12 10:51:09
【问题描述】:
我编写了一个简单的 Spring2.5 应用程序来演示/测试 AOP;具体来说,我想记录特定包中每个类的每个方法的进入和退出。这就是我所拥有的......
(注意:我正在使用注释控制器;我省略了与 aop 不直接相关的细节,因为我的基本设置工作正常——我只包括与 aop 相关的细节——如果您需要查看更多信息,请告诉我)
applicationContext.xml:
(...)
<bean id="loggerInterceptor" class="aspect.LoggerInterceptor" />
(...)
dispatcher-servlet.xml:
(...)
<aop:aspectj-autoproxy proxy-target-class="true" />
(...)
HomeController.java:
public class HomeController() {
public HomeController() { }
public ModelAndView get() {
System.out.println("In HomeController#get()...");
this.somePrivateMethod();
this.somePublicMethod();
return new ModelAndView( "home" );
}
private void somePrivateMethod() {
System.out.println("In HomeController#somePrivateMethod()...");
}
public void somePublicMethod() {
System.out.println("In HomeController#somePublicMethod()...");
}
}
LoggerInterceptor.java:
public class LoggerInterceptor {
@Pointcut("execution(* controller.*.*(..))")
private void anyOperationInControllerPackage() {
/* nothing to do here;
* this just defines that we want to catch all methods
* in the controller-package
*/
}
@Around("anyOperationInControllerPackage()")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Entering " + joinPoint.getSignature().getDeclaringTypeName() + "#" + joinPoint.getSignature().getName() + "() using arguments: " + Arrays.toString( joinPoint.getArgs() ) );
try {
Object result = joinPoint.proceed();
System.out.println("Leaving " + joinPoint.getSignature().getDeclaringTypeName() + "#" + joinPoint.getSignature().getName() + "()." );
return result;
} catch (Throwable ex) {
ex.printStackTrace();
throw ex;
}
}
}
这是调用 HomeController#get() 时得到的结果:
Entering controller.HomeController#get() using arguments: []
In HomeController#get()...
In HomeController#somePrivateMethod()...
In HomeController#somePublicMethod()...
Leaving controller.HomeController#get().
如您所见,唯一被拦截的方法是 HomeController#get()。当#get() 调用#somePrivateMethod() 或#somePublicMethod() 时,拦截器不会捕获这些。我希望,至少,#somePublicMethod() 也会被捕获(而且由于我使用的是 cglib,我也希望 #somePrivateMethod() 会被捕获)。
所以我想我的问题是我需要更改/添加什么才能允许(至少)控制器包中的所有公共方法被捕获,即使该包中的另一个方法调用它们并且它本身也是如此先抓到???
我希望这是有道理的。 :D
编辑(2011 年 4 月 25 日下午 1:13)
applicationContext.xml:
(...)
<context:load-time-weaver /> <!-- added -->
<bean id="loggerInterceptor"... />
(...)
aop.xml:
<!DOCTYPE aspectj PUBLIC
"-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver>
<!-- only weave classes in this package -->
<include within="controller.*" />
</weaver>
<aspects>
<!-- use only this aspect for weaving -->
<aspect name="aspect.LoggerInterceptor" />
</aspects>
</aspectj>
在 Netbean 的“运行”选项卡下的“项目属性”中,我将此行添加到“VM 选项”:
-javaagent:C:\Users\bgresham\Documents\libraries\spring-framework-2.5\dist\weaving\spring-agent.jar
和以前一样,我没有收到任何错误 - 我只是没有得到我正在寻找的“嵌套”日志记录。
???
【问题讨论】: