Let us now perform validation on method arguments by doing the following steps:
- This recipe will start with the creation of a class-level annotation which is not a transactional type, just like in the previous recipe. Using again the Reflection API, implement an annotation that will be used by an @Aspect to intercept parameter passing.
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface NegativeArgs { }
- Since a valid employee ID is a positive number, create an aspect that will validate if the empId argument passed onto readEmployee() of EmployeeServiceImpl is a non-negative number, using the custom annotation @NegativeArgs:
@Component @Aspect public class NegativeArgsAspect { private Logger logger = Logger.getLogger(NegativeArgsAspect.class); @Pointcut("execution(* *(@org.packt.aop.transaction.annotation.NegativeArgs (*), ..))") protected void myPointcut() { } @AfterThrowing(pointcut = "myPointcut() && args(empId)", throwing = "e") public void afterThrowingException(JoinPoint joinPoint, Exception e, Integer empId) { if(empId < 0){ logger.info("cannot be negative number"); } } @AfterReturning(pointcut = "myPointcut() && args(empId)") public void afterSuccessfulReturn(JoinPoint joinPoint, Integer empId) { if(empId < 0){ logger.info("cannot be negative number"); } } }
- Apply the annotation to the readEmployee() of EmployeeServiceImpl:
@MonitorService @Override public Employee readEmployee(@NegativeArgs Integer empId) { return employeeDaoImpl.getEmployee(empId); }
- Inside the test class TestEmployeeService, create a test method that will trigger the validation:
@Test public void testReadEmpMonitor(){ Employee emp = employeeServiceImpl.readEmployee(-11); }