仅使用注释使用 Spring AOP 拦截方法
在我的 Spring 上下文文件中,我有类似这样的内容:
<bean id="userCheck" class="a.b.c.UserExistsCheck"/>
<aop:config>
<aop:aspect ref="userCheck">
<aop:pointcut id="checkUser"
expression="execution(* a.b.c.d.*.*(..)) && args(a.b.c.d.RequestObject)"/>
<aop:around pointcut-ref="checkUser" method="checkUser"/>
</aop:aspect>
</aop:config>
abcUserExistsCheck 看起来像这样:
@Aspect
public class UserExistsCheck {
@Autowired
private UserInformation userInformation;
public Object checkUser(ProceedingJoinPoint pjp) throws Throwable {
int userId = ... //get it from the RequestObject passed as a parameter
if (userExists(userId)) {
return pjp.proceed();
} else {
return new ResponseObject("Invalid user);
}
}
用这些东西拦截的类看起来像这样:
public class Klazz {
public ResponseObject doSomething(RequestObject request) {...}
}
这有效。 UserExistCheck 在调用传递给 Klazz 之前根据需要执行。问题是这是我让它工作的唯一方法。通过使用注释而不是上下文文件来完成这项工作对于我的小大脑来说似乎太多了。那么...我到底应该如何注释 UserExistsCheck 和 Klazz 中的方法呢?我还需要其他东西吗?又一堂课?上下文文件中还有什么东西吗?
In my Spring context file I have something like this:
<bean id="userCheck" class="a.b.c.UserExistsCheck"/>
<aop:config>
<aop:aspect ref="userCheck">
<aop:pointcut id="checkUser"
expression="execution(* a.b.c.d.*.*(..)) && args(a.b.c.d.RequestObject)"/>
<aop:around pointcut-ref="checkUser" method="checkUser"/>
</aop:aspect>
</aop:config>
a.b.c.UserExistsCheck looks like this:
@Aspect
public class UserExistsCheck {
@Autowired
private UserInformation userInformation;
public Object checkUser(ProceedingJoinPoint pjp) throws Throwable {
int userId = ... //get it from the RequestObject passed as a parameter
if (userExists(userId)) {
return pjp.proceed();
} else {
return new ResponseObject("Invalid user);
}
}
And the class that is being intercepted with this stuff looks like this:
public class Klazz {
public ResponseObject doSomething(RequestObject request) {...}
}
This works. UserExistCheck is executed as desired before the call is passed to Klazz. The problem is that this is the only way I got it working. To get this working by using annotations instead of the context file seems to be just too much for my small brain. So... how exactly should I annotate the methods in UserExistsCheck and Klazz? And do I still need something else too? Another class? Still something in the context file?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您启用了基于注释的 AOP 吗? 文档< /a> 表示您必须添加
到您的 spring 配置中。然后您需要在
checkUser
方法前面添加注释。看起来您需要@Around
建议,如所述 此处。Have you enabled annotation-based AOP? The documentation says you have to add
to your spring configuration. Then you need to add an annotation in front of your
checkUser
method. It looks like you want@Around
advice, as described here.从您提供的示例代码来看,您似乎正在尝试为未实现任何接口的类创建建议。如代理机制中所述Spring 文档的部分,如果您要执行此操作,则需要启用 CGLIB:
我个人发现这比文档指示的更挑剔,尽管如果全部都有效,它确实可以工作星星排列得恰到好处,从设计的角度来看,在界面上声明 AOP 建议通常更容易,而且更可取,如下所示。 (请注意,您需要从
BeanFactory
/ApplicationContext
获取KlazzImpl
实例。)此外,您对
args
表达式有点偏离。请参阅以下内容:这些更改应该可以完成工作。
From the example code you've provided, it appears that you're trying to create advice for a class that doesn't implement any interfaces. As described in the Proxying Mechanisms section of the Spring docs, if you're going to do this, you'll need to enable CGLIB:
I've personally found this to be a bit more finicky than the documentation indicates it should be, and though it does work if all of the stars are aligned just right, it's often easier--and preferable from a design standpoint--to declare your AOP advice on an interface, as follows. (Note that you'll need to obtain your instance of
KlazzImpl
from yourBeanFactory
/ApplicationContext
.)Additionally, your use of the
args
expression is a little bit off. See the following:These changes should do the job.
从 spring 3.1 开始,将
@EnableAspectJAutoProxy(proxyTargetClass=true)
添加到您的@Configuraiton
since spring 3.1 add
@EnableAspectJAutoProxy(proxyTargetClass=true)
to your@Configuraiton