• 转载:Spring AOP (下)


      昨天记录了Spring AOP学习的一部分(http://www.cnblogs.com/yanbincn/archive/2012/08/13/2635413.html),本来是想一口气梳理完的。但是大晚上时间不够(无奈一场奥运篮球总决赛耗费掉了2小时,不过的确相当精彩),又考虑到篇幅太长,阅读性比较差,所以将后半部分更偏于应用的重起一篇随笔。

      利用方式一的配置起来,可见代码还是非常的厚重的,定义一个切面就要定义一个切面类,然而切面类中,就一个通知方法,着实没有必要。所以Spring提供了,依赖aspectj的schema配置和基于aspectj 注解方式。这两种方式非常简介方便使用,也是项目中普遍的使用方式。梳理之:

    4、方式二:schema配置

    a、业务类:

    复制代码
    /**
     * 业务类
     * 
     * @author yanbin
     * 
     */
    public class AspectBusiness {
    
        /**
         * 切入点
         */
        public String delete(String obj) {
            System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========
    ");
            return obj + ":瞄~";
        }
    
        public String add(String obj) {
            System.out.println("================这个方法不能被切。。。============== 
    ");
            return obj + ":瞄~ 嘿嘿!";
        }
    
        public String modify(String obj) {
            System.out.println("=================这个也设置加入切吧====================
    ");
            return obj + ":瞄改瞄啊!";
        }
    
    }
    复制代码

    b、切面类:切面类中,包含了所有的通知

    复制代码
    /**
     * 定义一个切面
     * 
     * @author yanbin
     * 
     */
    public class AspectAdvice {
    
        /**
         * 前置通知
         * 
         * @param jp
         */
        public void doBefore(JoinPoint jp) {
            System.out.println("===========进入before advice============ 
    ");
    
            System.out.print("准备在" + jp.getTarget().getClass() + "对象上用");
            System.out.print(jp.getSignature().getName() + "方法进行对 '");
            System.out.print(jp.getArgs()[0] + "'进行删除!
    
    ");
    
            System.out.println("要进入切入点方法了 
    ");
        }
    
        /**
         * 后置通知
         * 
         * @param jp
         *            连接点
         * @param result
         *            返回值
         */
        public void doAfter(JoinPoint jp, String result) {
            System.out.println("==========进入after advice=========== 
    ");
            System.out.println("切入点方法执行完了 
    ");
    
            System.out.print(jp.getArgs()[0] + "在");
            System.out.print(jp.getTarget().getClass() + "对象上被");
            System.out.print(jp.getSignature().getName() + "方法删除了");
            System.out.print("只留下:" + result + "
    
    ");
        }
    
        /**
         * 环绕通知
         * 
         * @param pjp
         *            连接点
         */
        public void doAround(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("===========进入around环绕方法!=========== 
    ");
    
            // 调用目标方法之前执行的动作
            System.out.println("调用方法之前: 执行!
    ");
    
            // 调用方法的参数
            Object[] args = pjp.getArgs();
            // 调用的方法名
            String method = pjp.getSignature().getName();
            // 获取目标对象
            Object target = pjp.getTarget();
            // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
            Object result = pjp.proceed();
    
            System.out.println("输出:" + args[0] + ";" + method + ";" + target + ";" + result + "
    ");
            System.out.println("调用方法结束:之后执行!
    ");
        }
    
        /**
         * 异常通知
         * 
         * @param jp
         * @param e
         */
        public void doThrow(JoinPoint jp, Throwable e) {
            System.out.println("删除出错啦");
        }
    
    }
    复制代码

    c、配置文件:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="     
              http://www.springframework.org/schema/beans     
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
              http://www.springframework.org/schema/context     
              http://www.springframework.org/schema/context/spring-context-3.0.xsd 
              http://www.springframework.org/schema/aop     
              http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
        default-autowire="byName">
    
        <!-- ==============================利用spring 利用aspectj来配置AOP================================ -->
    
        <!-- 声明一个业务类 -->
        <bean id="aspectBusiness" class="aop.schema.AspectBusiness" />
    
        <!-- 声明通知类 -->
        <bean id="aspectAdvice" class="aop.schema.advice.AspectAdvice" />
    
        <aop:config>
            <aop:aspect id="businessAspect" ref="aspectAdvice">
                <!-- 配置指定切入的对象 -->
                <aop:pointcut id="point_cut" expression="execution(* aop.schema.*.*(..))" />
                <!-- 只匹配add方法作为切入点
                <aop:pointcut id="except_add" expression="execution(* aop.schema.*.add(..))" />
                 -->
    
                <!-- 前置通知 -->
                <aop:before method="doBefore" pointcut-ref="point_cut" />
                <!-- 后置通知 returning指定返回参数 -->
                <aop:after-returning method="doAfter"
                    pointcut-ref="point_cut" returning="result" />
                <aop:around method="doAround" pointcut-ref="point_cut"/>
                <aop:after-throwing method="doThrow" pointcut-ref="point_cut" throwing="e"/>
            </aop:aspect>
        </aop:config>
    </beans>
    复制代码

    d、测试类:

    复制代码
    public class Debug {
    
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("aop/schema_aop.xml");
            AspectBusiness business = (AspectBusiness) context.getBean("aspectBusiness");
            business.delete("猫");
        }
    
    }
    复制代码

    5、方式三:aspectj注解

    注解在项目中已经到处都是了,撇开一些优劣不提,开发的便利性和可读性是非常的方便的。用来配置Spring AOP也非常简单便利

    a、业务类:

    复制代码
    /**
     * 业务类
     * 
     * @author yanbin
     * 
     */
    @Component
    public class Business {
    
        /**
         * 切入点
         */
        public String delete(String obj) {
            System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========
    ");
            return obj + ":瞄~";
        }
    
        public String add(String obj) {
            System.out.println("================这个方法不能被切。。。============== 
    ");
            return obj + ":瞄~ 嘿嘿!";
        }
    
        public String modify(String obj) {
            System.out.println("=================这个也设置加入切吧====================
    ");
            return obj + ":瞄改瞄啊!";
        }
    
    }
    复制代码

    b、切面类:

    复制代码
    /**
     * 定义切面
     * 
     * @Aspect : 标记为切面类
     * @Pointcut : 指定匹配切点
     * @Before : 指定前置通知,value中指定切入点匹配
     * @AfterReturning :后置通知,具有可以指定返回值
     * @AfterThrowing :异常通知
     * 
     * @author yanbin
     * 
     */
    @Component
    @Aspect
    public class AspectAdvice {
    
        /**
         * 指定切入点匹配表达式,注意它是以方法的形式进行声明的。
         */
        @Pointcut("execution(* aop.annotation.*.*(..))")
        public void anyMethod() {
        }
    
        /**
         * 前置通知
         * 
         * @param jp
         */
        @Before(value = "execution(* aop.annotation.*.*(..))")
        public void doBefore(JoinPoint jp) {
            System.out.println("===========进入before advice============ 
    ");
    
            System.out.print("准备在" + jp.getTarget().getClass() + "对象上用");
            System.out.print(jp.getSignature().getName() + "方法进行对 '");
            System.out.print(jp.getArgs()[0] + "'进行删除!
    
    ");
    
            System.out.println("要进入切入点方法了 
    ");
        }
    
        /**
         * 后置通知
         * 
         * @param jp
         *            连接点
         * @param result
         *            返回值
         */
        @AfterReturning(value = "anyMethod()", returning = "result")
        public void doAfter(JoinPoint jp, String result) {
            System.out.println("==========进入after advice=========== 
    ");
            System.out.println("切入点方法执行完了 
    ");
    
            System.out.print(jp.getArgs()[0] + "在");
            System.out.print(jp.getTarget().getClass() + "对象上被");
            System.out.print(jp.getSignature().getName() + "方法删除了");
            System.out.print("只留下:" + result + "
    
    ");
        }
    
        /**
         * 环绕通知
         * 
         * @param pjp
         *            连接点
         */
        @Around(value = "execution(* aop.annotation.*.*(..))")
        public void doAround(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("===========进入around环绕方法!=========== 
    ");
    
            // 调用目标方法之前执行的动作
            System.out.println("调用方法之前: 执行!
    ");
    
            // 调用方法的参数
            Object[] args = pjp.getArgs();
            // 调用的方法名
            String method = pjp.getSignature().getName();
            // 获取目标对象
            Object target = pjp.getTarget();
            // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
            Object result = pjp.proceed();
    
            System.out.println("输出:" + args[0] + ";" + method + ";" + target + ";" + result + "
    ");
            System.out.println("调用方法结束:之后执行!
    ");
        }
    
        /**
         * 异常通知
         * 
         * @param jp
         * @param e
         */
        @AfterThrowing(value = "execution(* aop.annotation.*.*(..))", throwing = "e")
        public void doThrow(JoinPoint jp, Throwable e) {
            System.out.println("删除出错啦");
        }
    
    }
    复制代码

    c、配置:

    复制代码
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xsi:schemaLocation="     
              http://www.springframework.org/schema/beans     
              http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     
              http://www.springframework.org/schema/context     
              http://www.springframework.org/schema/context/spring-context-3.0.xsd 
              http://www.springframework.org/schema/aop     
              http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
        default-autowire="byName">
    
        <context:component-scan base-package="aop.annotation" />
        <!-- 打开aop 注解 -->
        <aop:aspectj-autoproxy />
    
    </beans>
    复制代码

    d、测试类:

    复制代码
    /**
     * 测试类
     * 
     * @author yanbin
     * 
     */
    public class Debug {
    
        public static void main(String[] args) {
    
            ApplicationContext context = new ClassPathXmlApplicationContext("aop/annotation_aop.xml");
            Business business = (Business) context.getBean("business");
            business.delete("猫");
        }
    
    }
    复制代码
    分类: java web

    原文来自:http://www.cnblogs.com/yanbincn/archive/2012/08/13/2636961.html

  • 相关阅读:
    HDU 1754 I Hate It (线段树)
    HDU 1394 Minimum Inversion Number (树状数组)
    天梯赛 L2-012 关于堆的判断 (二叉树)
    HDU 1166 敌兵布阵 (树状数组 单点修改+区间查询)
    [leetcode-77-Combinations]
    [leetcode-101-Symmetric Tree]
    [leetcode-21-Merge Two Sorted Lists]
    [leetcode-109-Convert Sorted List to Binary Search Tree]
    [leetcode-507-Perfect Number]
    [leetcode-537-Complex Number Multiplication]
  • 原文地址:https://www.cnblogs.com/lucky-girl/p/3747825.html
Copyright © 2020-2023  润新知