1.多態
target指通過這個對象調用的方法 (匹配標識對象的所有方法) getMethod()
this指調用這個對象的方法 (匹配標識對象實現的方法) getDeclaredMethod()
target/this匹配類及其子類
2.
execution(* com.dao.BaseDao.*(..)) && target(com.dao.impl.UserDaoImpl)
通過UserDaoImpl對象調用<繼承><重寫><實現>自BaseDao的方法, 會被AOP增強; 如果是通過DeptDaoImpl調用的BaseDao方法就不會被AOP增強.
execution(* com.dao.*.*(..)) && this(com.dao.impl.UserDao)
通過UserDaoImpl對象調用<重寫><實現>自BaseDao的方法, 會被AOP增強; 如果UserDaoImpl並沒有Override-BaseDao的方法, 那么即使通過UserDaoImpl調用了BaseDao的方法也不會被Aop增強.
如果UserDaoImpl未重寫, 但UserDaoImpl的子類UserDaoImplSan重寫了, 那么UserDaoImplSan的這個方法會被Aop代理
this語義要強於target
3.關於繼承
execution() 匹配父類的某個方法, 那么aop對其子類的這個方法都有效, 即使子類重寫了父類的方法扔有效
execution() 匹配子類的某個方法, 如果這個方法是繼承自父類的, 那么只有當子類重寫了父類的這個方法, aop才對這個方法有效; 否則無效(即使execution不是通過通配符, 而是明確指定子類某個繼承方法, 也是無效的)
4.從上面可以看出, target和this主要是用加強某個已存在的pointcut, 如果不考慮復用, 對每個切入點都寫詳細的execution是可以避免使用target 和 this的
5.@annotation
@annotation表示匹配有這個注解的方法
關鍵:如何獲得注解的值
1.對於直接聲明並使用的切入點, 如@Before("@annotation(annoParam)"), 可以在增強方法的參數中直接聲明, spring會自動注入
@Before("@annotation(annoParam)") //這里是參數名
public void myAdvice(MyAnno annoParam){}
2.對於通過@Pointcut聲明, 或者和execution復合聲明的切入點, 如@Before("execution(xxx) && @annotation(MyAnno)), 要通過JoinPoint獲得
@Before("myPoint()") public void myAdvice(JoinPoint point){ Signature signature = point.getSignature(); Class clazz = signature.getDeclaringType(); //獲得被代理的類 MethodSignature methodSignature = (MethodSignature)signature; Method method = methodSignature.getMethod(); MyAnno myAnno = method.getAnnotation(MyAnno.class); }
//直接使用@annotation(X) X是增強方法的參數名