Spring 注解形式AOP

AOP 面向切面编程,通过预编译的方式,在运行期通过动态代理实现一种技术,AOP可实现业务与切面的逻辑分离,降低耦合度

一、注解形式的AOP

  Aspect:切面   

  Joinpoint:连接点,要拦截的方法

  Pointcut:切点,连接点的集合

  Advice:通知,在连接点前后,或异常情况来做的事情。  前置通知,后置通知,返回通知,异常通知,环绕通知

  Target:目标对象:代理的目标对象

  Weave:织入,切面应用到目标对象,并创建Proxy的过程

  1、导包:spring-aop   spring-aspect   aopalliance    weaver

  2、引入头信息:

xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=“http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"

  3、基于注解方式的切面声明

<!-- 开启以注解形式切面的驱动 -->
<aop:aspectj-autoproxy/>

  4、切面定义,创建一个类,上面加入@Aspect

 1 @Aspect
 2 public class PermAspect {
 3     /**
 4      * 第一个*  返回值类型
 5      * 第二个*  所有类
 6      * 第三个*  所有方法
 7      * 第一个.. 包及其子包
 8      * 第二个.. 所有参数
 9      */
10     @Pointcut("execution(* com.tx.spring..*.*(..))")
11     public void anyMethod(){
12         
13     }
14 }

  5、前置通知

 1 /**
 2  * 前置通知
 3  * anyMethod()  前置通知的切点
 4 * args中的参数名,要与方法名中的参数名一致
 5  */
 6 @Before(value="anyMethod()&&args(user)")
 7 public void preAdvice(User user){
 8     System.out.println(user);
 9     user.setUsername("张三");
10     System.out.println("执行前置通知");
11     System.out.println("---------------------");
12 }

  6、后置通知

 1 /**
 2 * 后置通知
 3 * anyMethod()  前置通知的切点
 4 * args中的参数名,要与方法名中的参数名一致
 5  */
 6 @After(value="anyMethod()&&args(user)")
 7 public void afterAdvice(User user){
 8     System.out.println("---------------------");
 9     System.out.println("执行后置通知");
10 }

  7、返回通知

/**
     * 返回通知,可以对业务方法的返回值进行统一加工
     */
    @AfterReturning(value="anyMethod()",returning="user")
    public void returnAdvice(User user){
        System.out.println("------------");
        user.setUsername("李四");
        System.out.println("执行返回通知");     
    }

  8、例外通知

/**
     * 例外通知
     * @param ex 抛出的异常
     */
    @AfterThrowing(pointcut="anyMethod()",throwing="ex")
    public void exceptionAdvice(Exception ex){
        System.out.println("执行例外通知");
        ex.printStackTrace();
    }

  9、环绕通知

/**
     * 环绕通知
     * @param jp 指定的连接点(要拦截的方法)
     */
    @Around("anyMethod()")
    public Object aroundAdvice(ProceedingJoinPoint jp){
        Object[] argsArr = jp.getArgs();
        System.out.println("环绕通知前-----参数是:"+argsArr[0]);
        
        Object obj = null;
        try {
            obj = jp.proceed();//执行要拦截的方法
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println("环绕通知后-----");
        return obj;
    }

 

posted @ 2018-04-03 08:44  cat_fish  阅读(149)  评论(0编辑  收藏  举报