Reputation: 1050
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?
Upvotes: 3
Views: 9051
Reputation: 401
since spring 3.1 add @EnableAspectJAutoProxy(proxyTargetClass=true)
to your @Configuraiton
Upvotes: 1
Reputation: 4444
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:
<aop:aspectj-autoproxy proxy-target-class="true" />
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 your BeanFactory
/ApplicationContext
.)
public interface Klazz {
ResponseObject doSomething(RequestObject request);
}
public class KlazzImpl implements Klazz {
public ResponseObject doSomething(RequestObject request) {...}
}
Additionally, your use of the args
expression is a little bit off. See the following:
@Aspect
public class UserExistsCheck {
@Autowired
private UserInformation userInformation;
@Around("execution(* a.b.c.d.*.*(..)) && args(reqObj)")
public Object checkUser(ProceedingJoinPoint pjp, a.b.c.d.RequestObject reqObj) throws Throwable {
// ...
}
}
These changes should do the job.
Upvotes: 3
Reputation: 6795
Have you enabled annotation-based AOP? The documentation says you have to add
<aop:aspectj-autoproxy/>
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.
@Aspect
public class UserExistsCheck {
@Around("execution(* a.b.c.d.*.*(..)) && args(a.b.c.d.RequestObject)")
public Object checkUser(ProceedingJoinPoint pjp) throws Throwable {
Upvotes: 5