@AspectJ可以使用切点函数定义切点, 我们还可以使用逻辑运算对切点进行复合运算得到复合的切点. 我们还可以对切点进行命名, 从而可以复用切点.当一个连接点匹配多个切点时, 需要考虑增强织入的顺序.还有一个在前面提到过的问题就是, 如何访问在增强中访问连接点上下文信息.下面对这几方面进行学习.

1.对切点进行复合运算

  使用切点进行复合运算, 使得我们能够拥有强大的表达切点的能力.例子如下:

package com.bao.bao.aspectj;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

/**
 * Created by xinfengyao on 16-10-26.
 */
@Aspect
public class TestAspect {
    // (1)
    @After("within(com.bao.bao.aspectj.*) && execution(* greetTo(..))")
    public void greetToFun() {
        System.out.println("...greetToFun() executed...");
    }

    //(2)
    @Before("!target(com.bao.bao.aspectj.NaiveWaiter) && execution(* serveTo(..))")
    public void noteServeInNaiveWaiter() {
        System.out.println("...notServeInNaiveWaiter() executed...");
    }

    // (3)
    @AfterReturning("target(com.bao.bao.aspectj.Waiter) || target(com.bao.bao.aspectj.Seller)")
    public void waiterOrSeller() {
        System.out.println("...waiterOrSeller() executed...");
    }
}

  在(1)处, 我们通过&&逻辑运算定义了一个匹配com.bao.bao.aspectj包中所有的greetTo()方法的切点.在(2)处, 我们通过!和&&逻辑运算定义了一个匹配serveTo()方法, 并且该方法不是NaiveWaiter或者其子类中的方法.在(3)我们通过||逻辑运算定义了一个匹配Waiter子类或者Seller子类的所有连接点的切点.

2.命名切点

  在前面的例子中, 切点直接定义在增强方法处, 这种切点声明方式称作为匿名切点.匿名切点只能在声明处使用.如果想在其他地方重用一个切点, 我们可以通过@Pointcut注解以及切面类方法对切点进行命名.如下:

package com.bao.bao.aspectj;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

/**
 * Created by xinfengyao on 16-10-26.
 */
@Aspect
public class TestNamePointcut {
    @Pointcut("within(com.bao.bao.*))")
    private void inPackage(){
    }

    @Pointcut("execution(* greetTo(..))")
    protected void greetTo() {
    }

    @Pointcut("inPackage() && greetTo()")
    public void inPkgGreetTo() {
    }
}

  命名切点定义好后, 我们就可以在定义切面时通过名称引用切点.如下所示:

@Before("TestNamePointcut.inPkgGreetTo()")
    public void pkgGreetTo() {
        System.out.println("...pkgGreetTo() executed...");
    }

    @Before("!target(com.bao.bao.aspectj.NaiveWaiter) && TestNamePointcut.inPkgGreetTo()")
    public void pkgGreetToNotNaiveWaiter() {
        System.out.println("...pkgGreetToNotNaiveWaiter() executed...");
    }

3.增强织入的顺序

  如果一个连接点匹配了多个切点,切点对应的增强在连接点上的织入顺序是如何确定的呢?这个问题要看情况:

  (1). 如果增强是在同一个切面中定义的, 则织入顺序按增强定义的顺序进行织入

  (2).如果增强是在不同切面中定义的, 但是这些切面类都实现了org.springframework.core.Ordered接口, 则由接口中方法的顺序号织入, 顺序号小的小织入.

  (3). 如果增强是在不同切面中定义的, 但是又没有实现Ordered接口, 则增强的织入顺序是不确定的.

4.如何访问连接点的信息

  AspectJ使用org.aspectj.lang.JoinPoint接口表示目标类连接点对象, 如果是环绕增强, 使用org.aspectj.lang.ProceedingJoinPoint表示连接点对象,该类是JoinPoint的子接口, 使用任何一个增强方法都可以通过将第一个入参声明为JoinPoint访问到连接点上下文的信息.下面看下这两个接口的主要方法:

  (1) JoinPoint

    String toShortString();

    String toLongString();

    Object getThis();  获取代理对象本身

    Object getTarget(); 获取连接点所在的目标对象

    Object[] getArgs(); //获取连接点方法运行时的入参列表

    Signature getSignature(); // 获取连接点的方法签名对象

  (2) ProceedingJoinPoint

 Object proceed() throws Throwable; //通过反射执行目标对象的连接点处的方法

 Object proceed(Object[] var1) throws Throwable;

基于@AspectJ和schema的aop(四)---@AspectJ进阶的更多相关文章

  1. 基于@AspectJ和schema的aop(二)---@AspectJ基础语法

    @AspectJ使用jdk5.0和正规的AspectJ切点表达式描述切面, 由于spring只支持方法的连接点,所以Spring只支持部分AspectJ的切点语言. 1.切点表达式函数 AspectJ ...

  2. 基于@AspectJ和schema的aop(一)

    在前面我们使用Pointcut和Advice描述切点和增强, 并使用Advisor整合两者描述切面.@AspectJ使用注解来描述切点和增强.两者使用的方式不同, 但是在本质上都是一样的. 我们还是用 ...

  3. spring3: schema的aop与Aspectj的aop的区别

    schema的aop如下: 接口: package chapter6.service; public interface IHelloAroundService { public void sayAr ...

  4. (spring-第19回【AOP基础篇】)基于AspectJ和Schema的AOP

    基于AspectJ就是基于@AspectJ注解,基于Schema就是全部依靠配置文件.那么首先要了解Java注解. Java注解初探 在JDK5.0中,我们可以自定义标签,并通过Java语言的反射机制 ...

  5. 基于@AspectJ和schema的aop(三)---切点函数详解

    切点函数是AspectJ表达式语言的核心, 也是使用@AspectJ进行切面定义的难点.本小节我们通过具体的实例对切点函数进行深入学习. 1.@annotation() @annotation()表示 ...

  6. Spring学习之旅(七)基于XML配置与基于AspectJ注解配置的AOP编程比较

    本篇博文用一个稍复杂点的案例来对比一下基于XML配置与基于AspectJ注解配置的AOP编程的不同. 相关引入包等Spring  AOP编程准备,请参考小编的其他博文,这里不再赘述. 案例要求: 写一 ...

  7. Spring中基于AOP的@AspectJ

    以下内容引用自http://wiki.jikexueyuan.com/project/spring/aop-with-spring-framenwork/aspectj-based-aop-with- ...

  8. Spring Aop(二)——基于Aspectj注解的Spring Aop简单实现

    转发地址:https://www.iteye.com/blog/elim-2394762 2 基于Aspectj注解的Spring Aop简单实现 Spring Aop是基于Aop框架Aspectj实 ...

  9. Spring 中基于 AOP 的 @AspectJ

    Spring 中基于 AOP 的 @AspectJ @AspectJ 作为通过 Java 5 注释注释的普通的 Java 类,它指的是声明 aspects 的一种风格. 通过在你的基于架构的 XML ...

随机推荐

  1. Leetcode: Convert a Number to Hexadecimal

    Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two's compl ...

  2. 【Origin】工仕途中

    -脚步翩跹,随蝶起舞,翩翩不知所往 晨起脚步催, 蝴蝶迎面飞; 正是春意浓, 三月好风景. -作于二零一六年三月二十八日

  3. each实现原理

    <script> function isEach(arr, callback) { for (var i in arr) { callback(i, arr[i]); } }; funct ...

  4. Java基础(10):java基础第一部分综合测试题,成绩合法性校验与排序

    题目: 编写一个 JAVA 程序,实现输出考试成绩的前三名 要求: 1. 考试成绩已保存在数组 scores 中,数组元素依次为 89 , -23 , 64 , 91 , 119 , 52 , 73 ...

  5. linux时间的查看与修改

    1.查看时间和日期 date 2.设置时间和日期 将系统日期设定成1996年6月10日的命令 date -s 06/22/96 将系统时间设定成下午1点52分0秒的命令 date -s 13:52:0 ...

  6. paper 61:计算机视觉领域的一些牛人博客,超有实力的研究机构等的网站链接

    转载出处:blog.csdn.net/carson2005 以下链接是本人整理的关于计算机视觉(ComputerVision, CV)相关领域的网站链接,其中有CV牛人的主页,CV研究小组的主页,CV ...

  7. ios学习笔记(一)Windows7上使用VMWare搭建iPhone开发环境(转)

    原文地址:http://blog.csdn.net/shangyuan21/article/details/18153605 我们都知道开发iPhone等ios平台的移动应用时需要使用Mac本,但是M ...

  8. zw·准专利·高保真二值图细部切分算法

    zw·准专利·高保真二值图细部切分算法     高保真二值图细部切分算法,是中国字体协会项目的衍生作品.     说准专利算法,是因为对于图像算法的标准不了解,虽然报过专利,但不是这方面的,需要咨询专 ...

  9. Debian类系统必做——将【你的用户】加入sudoers用户组

    切换到root:su root   修改sudoers nano /etc/sudoers 在root    ALL=(ALL:ALL) ALL下,加入:liz        ALL=(ALL:ALL ...

  10. asp.net中获得客户端的IP地址

    asp.net中获得客户端的IP地址 因为要在项目中取到客户端IP,在网上搜了下相关资料,其中有一篇文章总结的比较详细,这里就把一些我用的上总结一下 方便以后查阅.  通常我们都通过下面的代码获得IP ...