gpt4 book ai didi

Spring AOP : logging and nested-methods

转载 作者:行者123 更新时间:2023-12-04 14:34:06 25 4
gpt4 key购买 nike

我编写了一个简单的 Spring2.5 应用程序来演示/测试 AOP;具体来说,我想记录特定包中每个类的每个方法的进入和退出。这就是我所拥有的...

(注意:我正在使用注释 Controller ;我省略了与 aop 不直接相关的细节,因为我的基本设置工作正常——我只包括与 aop 相关的细节——如果您需要查看更多信息,请告诉我)

applicationContext.xml :

(...)
<bean id="loggerInterceptor" class="aspect.LoggerInterceptor" />
(...)

调度程序-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() 会被捕获)。

所以我想我的问题是我需要更改/添加什么以便(至少)允许 Controller 包中的所有公共(public)方法被捕获,即使该包中的另一个方法调用它们并且本身首先被捕获? ??

我希望这是有道理的。
: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

和以前一样,我没有收到任何错误——我只是没有得到我正在寻找的“嵌套”日志。

???

最佳答案

如果你使用 Spring AOP,你只能调用一个通过 Spring 返回的引用而不是通过 this 应用了切面的方法。 ,而且我认为您也不能将切入点应用于私有(private)方法(最后一部分可能是错误的)。这是因为 Spring AOP 通过代理对象应用切入点,而不是通过类重写(这是 AspectJ 所做的)。这种严格限制的好处是它更容易在容器中工作(我从经验中知道 Spring AOP 在 Tomcat 中工作得很好),因为对于插入什么位在哪里没有争论。

最好的方法是拆分类定义,这样你就不会通过 this 调用方法。 ,但如果这不可能,那么您总是可以尝试为 bean 提供一个 Spring 派生的对其自身的引用:

private HomeController self;
@Required
public void setSelf(HomeController self) { this.self = self; }

public ModelAndView get() {
System.out.println("In HomeController#get()...");

self.somePrivateMethod();
self.somePublicMethod();

return new ModelAndView( "home" );
}

(这非常简洁; self 是许多语言中的关键字,但不是 Java,因此相对容易记住您使用它的目的。)

关于 Spring AOP : logging and nested-methods,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5780757/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com