Update: I forgot to mention that @args() is not meant to match a parameter's annotation, but a parameter type's annotation, which is not what you want and which thus I do not use here.
You cannot bind a parameter's annotation via args(), only the parameter itself. This means that you can only access the parameter's annotation via reflection. You need to determine the method signature, create a Method object from it and then iterate over the method parameters' annotations. Here is a full code sample:
package com.mycompany.locking; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Lock {}
package com.mycompany.locking; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface LockVal { String value() default ""; }
package com.mycompany; public class MyBatchObject {}
package com.mycompany; public interface UpdateManager { public void processUpdate(MyBatchObject batch); }
package com.mycompany; import com.mycompany.locking.Lock; import com.mycompany.locking.LockVal; public class UpdateManagerImpl implements UpdateManager { @Lock @Override public void processUpdate(@LockVal("lockValue") MyBatchObject batch) { System.out.println("Processing update"); } public static void main(String[] args) { UpdateManager updateManager = new UpdateManagerImpl(); updateManager.processUpdate(new MyBatchObject()); } }
package com.mycompany.aop; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import com.mycompany.MyBatchObject; import com.mycompany.locking.LockVal; @Aspect public class MyAspect { @Pointcut("execution(@com.mycompany.locking.Lock * *(@com.mycompany.locking.LockVal (*), ..)) && args(batch)") public void lockedMethod(MyBatchObject batch) {} @Around("lockedMethod(batch)") public Object lockAndProceed(ProceedingJoinPoint pjp, MyBatchObject batch) throws Throwable { System.out.println(pjp); System.out.println(batch); MethodSignature methodSignature = (MethodSignature) pjp.getSignature(); Class<?> clazz = methodSignature.getDeclaringType(); Method method = clazz.getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes()); LockVal propertyToLock; for (Annotation ann : method.getParameterAnnotations()[0]) { if(LockVal.class.isInstance(ann)) { propertyToLock = (LockVal) ann; System.out.println(propertyToLock.value()); } } return pjp.proceed(); } }
When I run UpdateManagerImpl.main, I see the following output, just as expected:
execution(void com.mycompany.UpdateManagerImpl.processUpdate(MyBatchObject)) com.mycompany.MyBatchObject@86f241 lockValue Processing update
Disclaimer: I am not a Spring guy, I just tested this with plain AspectJ, not Spring AOP.