Aspectj 没有捕获 Spring 框架中的所有事件?
我的项目基于spring框架2.5.4。 我尝试为某些控制器添加方面(我使用aspectj 1.5.3)。
我已在 application-servlet.xml 中启用自动代理,只需将这些行粘贴到 xml 文件的末尾:
<aop:aspectj-autoproxy />
<bean id="auditLogProcessor" class="com.example.bg.web.utils.AuditLogProcessor" />
创建方面:
package com.example.bg.web.utils;
import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AuditLogProcessor
{
private final static Logger log = Logger.getLogger(AuditLogProcessor.class);
@After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
public void afterHandleRequest() {
log.info("test111");
}
@After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
public void afterRebuildThumbnail() {
log.info("test222");
}
}
我的控制器:
class AssetAddController implements Controller
class AssetThumbnailRebuildController extends MultiActionController
当我在方面顾问中设置制动点并调用控制器时,我仅捕获 afterHandleRequest() 但不在 RebildThumbnail() 之后 我做错了什么?
注意
我是代表我的朋友问这个问题的,他无法访问 SO beta,而且我不知道这是什么意思。
编辑
确实有一些拼写错误,谢谢 Cheekysoft。 但问题仍然存在。
My project is based on spring framework 2.5.4. And I try to add aspects for some controllers (I use aspectj 1.5.3).
I've enabled auto-proxy in application-servlet.xml, just pasted these lines to the end of the xml file:
<aop:aspectj-autoproxy />
<bean id="auditLogProcessor" class="com.example.bg.web.utils.AuditLogProcessor" />
Created aspect:
package com.example.bg.web.utils;
import org.apache.log4j.Logger;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
@Aspect
public class AuditLogProcessor
{
private final static Logger log = Logger.getLogger(AuditLogProcessor.class);
@After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
public void afterHandleRequest() {
log.info("test111");
}
@After("execution(* com.example.bg.web.controllers.assets.AssetThumbnailRebuildController.rebuildThumbnail(..))")
public void afterRebuildThumbnail() {
log.info("test222");
}
}
My controllers:
class AssetAddController implements Controller
class AssetThumbnailRebuildController extends MultiActionController
When I set brake points in aspect advisors and invoke controllers I catch only afterHandleRequest() but not afterRebildThumbnail()
What did I do wrong?
NOTE
I'm asking this question on behalf of my friend who doesn't have access to SO beta, and I don't have a clue what it's all about.
EDIT
There were indeed some misspellings, thanks Cheekysoft. But the problem still persists.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
AspectJ 不能很好地与 Spring Web MVC 框架中的类配合使用。 阅读“打开以进行扩展...”框的底部相反
,请查看 HandlerInterceptor 接口。
新的 Spring MVC Annotations 可能也可以工作,因为控制器类都是 POJO,但我自己还没有尝试过。
AspectJ doesn't work well with classes in the Spring Web MVC framework. Read the bottom of the "Open for extension..." box on the right side of the page
Instead, take a look at the HandlerInterceptor interface.
The new Spring MVC Annotations may work as well since then the Controller classes are all POJOs, but I haven't tried it myself.
你的断点没有被击中,因为你正在使用 Spring 的 AOP 代理。 请参阅 understanding-aop-proxies 了解 AOP 代理有何特殊之处。
基本上,MVC 框架将调用控制器代理上的
handleRequest
方法(例如,您用作基类实现的MultiActionController
),此方法将然后对其rebuildThumbnail方法进行“内部”调用,但这不会通过代理,因此不会获取任何方面。 (这与最终的方法无关。)为了实现你想要的,请研究通过加载时编织(Spring 很好地支持)使用“真正的”AOP。
Your breakpoints aren't being hit because you are using Spring's AOP Proxies. See understanding-aop-proxies for a description of how AOP Proxies are special.
Basically, the MVC framework is going to call the
handleRequest
method on your controller's proxy (which for example theMultiActionController
you're using as a base class implements), this method will then make an "internal" call to its rebuildThumbnail method, but this won't go through the proxy and thus won't pick up any aspects. (This has nothing to do with the methods being final.)To achieve what you want, investigate using "real" AOP via load time weaving (which Spring supports very nicely).
基本设置看起来没问题。
通过不定义就地切入点并仅指定应应用后续建议的方法,可以稍微简化语法。 (方法的命名切入点会自动为您创建。)
例如,
只要rebuildThumbnail 方法不是最终的,并且方法名称和类是正确的。 我不明白为什么这行不通。
参见 http://static.springframework.org/spring/docs /2.0.x/reference/aop.html
The basic setup looks ok.
The syntax can be simplified slightly by not defining an in-place pointcut and just specifying the method to which the after-advice should be applied. (The named pointcuts for methods are automatically created for you.)
e.g.
As long as the rebuildThumbnail method is not final, and the method name and class are correct. I don't see why this won't work.
see http://static.springframework.org/spring/docs/2.0.x/reference/aop.html
这就像拼写一样简单吗? 或者问题中只是有拼写错误?
有时你会写
rebuildThumbnail
,有时你会写rebildThumbnail
你试图用建议覆盖的方法不是 MVC 框架中的最终方法,所以虽然 bpapas 答案很有用,但我的理解是,这不是本例中的问题。 但是,请确保
rebuildThumbnail
控制器操作不是最终的@bpapas:如果我错了,请纠正我。 程序员自己的控制器操作是他试图覆盖的。 查看 MultiActionController 源(及其父级),堆栈中唯一可能的最终确定方法是 MultiActionController.invokeNamedMethod,尽管我不能 100% 确定当时是否会在堆栈中,或者不是。 在堆栈上方有一个最终确定的方法是否会导致向下方的方法添加 AOP 建议时出现问题?
Is this as simple as spelling? or are there just typos in the question?
Sometimes you write
rebuildThumbnail
and sometimes you writerebildThumbnail
The methods you are trying to override with advice are not final methods in the MVC framework, so whilst bpapas answer is useful, my understanding is that this is not the problem in this case. However, do make sure that the
rebuildThumbnail
controller action is not final@bpapas: please correct me if I'm wrong. The programmer's own controller action is what he is trying to override. Looking at the MultiActionController source (and its parents') the only finalized method potentially in the stack is
MultiActionController.invokeNamedMethod
, although I'm not 100% sure if this would be in the stack at that time or not. Would having a finalized method higher up the stack cause a problem adding AOP advice to a method further down?