aspectj 学习一 :切点切面各种实现_第1张图片

一:自定义注解型

1:自定义注解类:

@Retention(RetentionPolicy.RUNTIME)
public @interface pointcutTest {
}

2:

@Aspect
@Component
@Order(0)
public class pointcut {
//此处两种写法
//一:
//    @Pointcut("@annotation(application.anntation.pointcutTest)")
//    public void pointcut(){}
//二:打开上面注释,将下面的@annotation(application.anntation.pointcutTest)替换成pointcut()
    @Before("@annotation(application.anntation.pointcutTest)")
    public void beforeRunning() {
        System.out.println("pointcutTest1 @before方法开始前执行");
    }

    @Around("@annotation(application.anntation.pointcutTest)")
    //此处注意有返回时 around需添加object的返回值,不然会导致原来的返回值不返回
    public Object beforeExecute(final ProceedingJoinPoint joinPoint) throws Throwable {
        Object obj = null;
        try {
            System.out.println("pointcutTest1 @around方法开始前执行1");
            System.out.println(JSON.toJSONString(joinPoint.getArgs()));
            //.proceed()此处为通知处理,会先去执行before方法,切点进来后会先进入around方法
            obj = joinPoint.proceed();
            System.out.println("pointcutTest1  @before方法执行后执行");
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
            System.out.println("方法执行错误");
        }
        return obj;
    }

    @After("@annotation(application.anntation.pointcutTest)")
    public void after(final JoinPoint joinPoint) {
        try {
            System.out.println("pointcutTest1 @after方法执行后执行");
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
            System.out.println("方法执行错误");
        }
    }

    @AfterReturning("@annotation(application.anntation.pointcutTest)")
    public JoinPoint afterExecute(final JoinPoint joinPoint) {
        try {
            System.out.println("pointcutTest1 @AfterReturning方法执行后执行");
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
            System.out.println("方法执行错误");
        }
        return joinPoint;
    }

以上,所有加了@pointcutTest注解的方法都会被切到,进行增强处理


二:无注解标识,主动切

@Aspect
@Component
@Order(2)
public class pointcutTest2 {
    @Pointcut("execution(* application.controller.test.test())")
    public void pointcut(){}

    @Before("pointcut()")
    public void beforeExecute(final JoinPoint joinPoint) {
        try {
            System.out.println("pointcutTest2 @Before 方法开始执行");
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
            System.out.println("方法执行错误");
        }
    }
    @Around("pointcut()")
    public Object beforeExecute(final ProceedingJoinPoint joinPoint) throws Throwable {
        Object obj=null;
        try {
            System.out.println("pointcutTest2 @around方法开始前执行");
            System.out.println( JSON.toJSONString(joinPoint.getArgs()));
            obj= joinPoint.proceed();
            System.out.println("pointcutTest2 @Before方法执行后执行");
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
            System.out.println("方法执行错误");
        }
        return obj;
    }
    @AfterReturning(pointcut = "pointcut()",returning = "fileurl")
    public JoinPoint afterExecute(final JoinPoint joinPoint ,String fileurl) {
        try {
            System.out.println(fileurl);
            System.out.println(JSON.toJSONString(joinPoint.getArgs()));
            System.out.println("pointcutTest2 AfterReturning方法执行后执行");
        } catch (Exception e) {
//            logger.error("发生异常: ", e);
            System.out.println("方法执行错误");
        }
        return joinPoint;
    }

}

自定义方法,添加注解@Pointcut("execution(* application.controller.test.test())"),此注解表示切test类里面的test方法,当执行test方法时,就会进行增强处理



三:对于可以使用配置的文件的项目,可使用配置文件实现切点
此种方法跟上面第一种一样,是自定义注解方法的配置文件形式
1、
指定处理类
2、
指定自定义的注解

3、
 

指定执行的方法及处理时机

指定执行的时间 before、around、after
order 当同一个方法被多个切点切时的执行顺序,数字越小越先执行
method 指定执行哪一个方法


四:execution详解
示例一:

第一个* 表示任意返回值类型
第二个*表示以任意名字开头的package,如com.xx
第三个*表示以任意名字开头的class的类名 如TestService
第四个*表示通配*Service下面的任意class
最后的..表示通配方法可以有0个或者多个参数

示例二:
execution(* com.aptech.jb.epet.dao.hibimpl.*.*(..))
这样是匹配hibimpl包下面的所有的类的所有方法
第一个* 表示任意返回值类型
第二个*表示所有的类
第四个*表示所有的方法
最后的..表示通配方法可以有0个或者多个参数


使用execution时可以切一个类里面的全部方法,或者一个包里面全部类里面的全部方法,也可以切单个方法,使用@annotation时,可以自由的给想要切的方法标识注解,两种方法按实际场景需求选择。