Spring Aop: 关于继承和execution target this @annotation

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是增强方法的参数名

posted @ 2017-03-24 13:08  长乐忘忧  阅读(6500)  评论(0编辑  收藏  举报