Reputation: 3318
I have to throw an exception if a method parameter is a particular value. The aim is to lock all the method that work with the specific value so I thought to use Spring AOP but I am new with it. My problem is retrieve the value of method parameter, I create this sample:
Annotation
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAOPAnnotation {
}
AOP class
@Component
@Aspect
public class TestAOP {
@Before("@annotation(TestAOPAnnotation)")
public void logAOP(){
//Make some operations with database and throw exception in a specific case
throw new RuntimeException();
}
}
The method where I use the annotation
@Override
@TestAOPAnnotation
public List<Animals> findByName(String name) throws QueryException {
try{
return animalsRepository.findByName(name);
}catch(Exception e){
throw new QueryException(e);
}
}
and where I catch the exception
@Override
@RequestMapping(value="/test/{name}", method = RequestMethod.GET)
public @ResponseBody List<Animals> findByName(@PathVariable String name){
try{
return databaseAnimalsServices.findByName(name);
}catch(QueryException e){
return null;
}catch(Exception e){
//CATCH AOP EXCEPTION
List<Animals> list = new ArrayList<Animals>();
list.add(new Animals("AOP", "exception", "test"));
return list;
}
}
How can I get the name parameter? I may use another annotation on parameter (or only this annotation) but I don't know how. Can you help me?
EDIT To catch parameter annotation I may use:
@Before("execution(* *(@Param (*),..))")
but it works only if I know the parameters order instead I need only the annotated parameter. Otherwise , until now, the best solution is
@Before("@annotation(TestAOPAnnotation) && args(name,..)")
public void logAOP(String name){
System.out.println(name);
throw new RuntimeException("error");
}
but the parameter must be the fist in the signature
Upvotes: 0
Views: 5730
Reputation: 7950
You can get the calling arguments from the joinPoint:
@Around(.....)
public Object check(ProceedingJoinPoint joinPoint) {
for (Object object : joinPoint.getArgs()) {
.... add your checks here.
}
return joinPoint.proceed();
}
Note you can not easily get the name of the parameter from the joinPoint (like you can in .NET) but you could check on type and value.
See https://blog.espenberntsen.net/2010/03/20/aspectj-cheat-sheet/ for valid execution patterns.
Upvotes: 0
Reputation: 11835
You could use an @Around
advice which has access to the invocation data.
@Around("@annotation(TestAOPAnnotation)")
public Object logAOP(ProceedingJoinPoint aPoint) throws Throwable {
// First, implement your checking logic
// aPoint.getArgs() may be inspected here ...
if (...) {
throw new RuntimeException(...);
}
// now, actually proceed with the method call
return aPoint.proceed();
}
getArgs()
gives you access to the real arguments passed to the method.
Upvotes: 1