ITPub博客

首页 > IT职业 > IT职场 > 手把手教你学会用Spring AOP

手把手教你学会用Spring AOP

IT职场 作者:kikiv 时间:2021-09-09 09:34:41 0 删除 编辑

 用了Spring很长时间了,一直想写些AOP的东西,但一直没有空闲,直到现在项目稍微进入正轨了,才赶紧写写。废话不多说,先从AOP入门开始,后面再介绍AOP的原理(JDK动态代码和CGLIB动态代码的知识)。注:该部分适合于未接触过Spring AOP的童鞋,如果是AOP老手,请直接绕过,不用打招呼^^

       请尊重作者劳动成果,转载请标明原文链接:

       https://www.cnblogs.com/jpcflyer/p/9339104.html

一、环境准备

       1.在Spring官网(地址见本文最后)下载springframework相关jar包,下载完后的jar包里面会包含aop/aspects/context/beans/core等相关的jar。

       2.在AspectJ官网(AOP依赖包,地址见本文最后)下载AspectJ.jar,目前最新稳定版是1.9.1。

       3.在Eclipse中,新建java project,然后在根目录下新建lib目录,并将第1步中下载的jar包全部copy到lib目录下。

       4.将第2步下载的AspectJ.jar解压,并将解压后的aspectjrt.jar、aspectjweaver.jar两个jar包copy到lib目录下。

       5.项目右键-build path-libraries-add jars,然后选择lib中的全部jar包,点击确定。

       6.在项目根目录下新建配置文件applicationContext.xml,文件内容暂时为空,到此环境准备完毕。

二、代码示例

       了解AOP的童鞋都知道,使用AOP的方式有多少,这里建议使用配置文件的方式,能够减少对代码的注入,比较简洁。

       1.新建切面类

图片描述

package test;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class AspectAdvice {     /**
     * 前置通知
     * 
     * @param jp     */
    public void doBefore(JoinPoint jp) {
        System.out.println("===========进入before advice============ n");

        System.out.print("准备在" + jp.getTarget().getClass() + "对象上用");
        System.out.print(jp.getSignature().getName() + "方法进行对 '");
        System.out.print(jp.getArgs()[0] + "'进行删除!nn");

        System.out.println("要进入切入点方法了 n");
    }    /**
     * 后置通知
     * 
     * @param jp
     *            连接点
     * @param result
     *            返回值     */
    public void doAfter(JoinPoint jp, String result) {
        System.out.println("==========进入after advice=========== n");
        System.out.println("切入点方法执行完了 n");

        System.out.print(jp.getArgs()[0] + "在");
        System.out.print(jp.getTarget().getClass() + "对象上被");
        System.out.print(jp.getSignature().getName() + "方法删除了");
        System.out.print("只留下:" + result + "nn");
    }    /**
     * 环绕通知
     * 
     * @param pjp
     *            连接点     */
    public void doAround(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("===========进入around环绕方法!=========== n");        // 调用目标方法之前执行的动作
        System.out.println("调用方法之前: 执行!n");        // 调用方法的参数
        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 + "n");
        System.out.println("调用方法结束:之后执行!n");
    }    /**
     * 异常通知
     * 
     * @param jp
     * @param e     */
    public void doThrow(JoinPoint jp, Throwable e) {
        System.out.println("删除出错啦");
    }


}

图片描述

       2.新建业务类

图片描述

package test;public class AspectBusiness {    public String delete(String obj) {
        System.out.println("==========调用切入点:" + obj + "说:你敢删除我!===========n");        return obj + ":瞄~";
    }    public String add(String obj) {
        System.out.println("================这个方法不能被切。。。============== n");        return obj + ":瞄~ 嘿嘿!";
    }    public String modify(String obj) {
        System.out.println("=================这个也设置加入切吧====================n");        return obj + ":瞄改瞄啊!";
    }


}

图片描述

       3.在applicationContext.xml中添加如下内容

图片描述

<!-- bean definitions here -->



    <!-- 声明一个业务类 -->
    

    <!-- 声明通知类 -->
    

    
        
            <!-- 配置指定切入的对象 -->
            
            <!-- 只匹配add方法作为切入点            
             -->

            <!-- 前置通知 -->
            
            <!-- 后置通知 returning指定返回参数 -->
            
            
            
        
    

图片描述

       4.新建测试类

图片描述

package test;import java.util.ArrayList;import java.util.Collection;import java.util.LinkedList;import java.util.List;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class StringTest {    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        AspectBusiness business = (AspectBusiness) context.getBean("aspectBusiness");
        business.delete("猫");
    }
}

图片描述

三、运行结果

       运行结果如下所示:

图片描述

===========进入before advice============ 准备在class test.AspectBusiness对象上用delete方法进行对 '猫'进行删除!

要进入切入点方法了 

===========进入around环绕方法!=========== 调用方法之前: 执行!==========调用切入点:猫说:你敢删除我!===========输出:猫;delete;test.AspectBusiness@3b69e7d1;猫:瞄~

调用方法结束:之后执行!==========进入after advice=========== 切入点方法执行完了 

猫在class test.AspectBusiness对象上被delete方法删除了只留下:null

图片描述

       这样AOP的示例就算完成了,本篇先不介绍切面、通知、切入点等的相关概念了,这些概念在百度上可谓信手拈来,如果有不了解,可以自行百度。本篇先写到这里,后续再介绍AOP的相关原理。

 

       参考资料:

       1. Spring官网:https://spring.io/

       2. Spring4.0官网下载地址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframework/spring/5.0.0.RELEASE

       3. AspectJ最新稳定版官网下载地址:http://www.eclipse.org/aspectj/downloads.php#stable_release

原文出处


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/3585/viewspace-2804876/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-14

  • 博文量
    68
  • 访问量
    820