How to wrap a method with try-catch by annotation?

Viewed 3500

If an exception should be ignored inside a method call, one would write eg the following:

public void addEntryIfPresent(String key, Dto dto) {
   try {
        Map<String, Object> row = database.queryForMap(key);
        dto.entry.put(row);
   } catch (EmptyResultDataAccessException e) {}
}

I'm trying to write eg a custom spring annotation that has the same effect, but could just be applied to the method header. That could look similar to the following:

@IgnoreException(EmptyResultDataAccessException.class) //this annotation does not exist
public void addEntryIfPresent(String key, Dto dto) {
   Map<String, Object> row = database.queryForMap(key);
   dto.entry.put(row);
}

How could such an annotation be created?

1 Answers

Here is a way of doing it with AspectJ.

First of all, define a method level annotation.

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface IgnoreRuntimeException{

}

Then, define an around aspect for the annotation.

@Component
@Aspect
public class ExceptionHandlingAdvice {

    @Around("@annotation(com.yourpackage.IgnoreRuntimeException) && execution(* *(..))")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
        Object returnObject = null;
        // do something before the invocation
        try {
            // invoke method
            returnObject = joinPoint.proceed();
            // do something with the returned object
            return returnObject;
        } catch (Exception e) {
            // do something with the exception
        }
    }

}

You can then apply the annotation on top of your methods to ignore exceptions.

@IgnoreRuntimeException
public void addEntryIfPresent(String key, Dto dto) {
    // ...
}

You can also check the parameters of the annotation using the api of ProceedingJoinPoint to ignore only the exceptions that you'd like to ignore.

Related