用了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] + "'进行删除!\n\n"); 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 + "\n\n");
} /**
* 环绕通知
*
* @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中添加如下内容

<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd"
> <!-- bean definitions here --> <!-- 声明一个业务类 -->
<bean id="aspectBusiness" class="test.AspectBusiness" /> <!-- 声明通知类 -->
<bean id="aspectAdvice" class="test.AspectAdvice" /> <aop:config>
<aop:aspect id="businessAspect" ref="aspectAdvice">
<!-- 配置指定切入的对象 -->
<aop:pointcut id="point_cut" expression="execution(* test.*.*(..))" />
<!-- 只匹配add方法作为切入点
<aop:pointcut id="except_add" expression="execution(* test.*.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>

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. Spring5.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

手把手教你学会用Spring AOP的更多相关文章

  1. 手把手教你整合 SpringMvc+Spring+MyBatis+Maven

    注:该教程是参考孙宇老师的<SpringMvc+Spring+Mybatis+Maven整合视频教程1>整理的,花了我六个多小时,边复习视频边调代码边写教程,保证该教程每一步都能正确执行, ...

  2. 手把手教你学会 Emacs 定制

    Table of Contents 1 前言 2 配置Emacs 2.1 设置界面 2.2 全屏以及最大化 2.3 设置周边 2.4 显示时间设置 2.5 设置日历 2.6 设置符合个人的操作习惯 2 ...

  3. 手把手教你学会 基于JWT的单点登录

      最近我们组要给负责的一个管理系统 A 集成另外一个系统 B,为了让用户使用更加便捷,避免多个系统重复登录,希望能够达到这样的效果--用户只需登录一次就能够在这两个系统中进行操作.很明显这就是单点登 ...

  4. 手把手教你定制标准Spring Boot starter,真的很清晰

    写在前面 我们每次构建一个 Spring 应用程序时,我们都不希望从头开始实现具有「横切关注点」的内容:相反,我们希望一次性实现这些功能,并根据需要将它们包含到任何我们要构建的应用程序中 横切关注点 ...

  5. 手把手教你实现自定义Spring Boot的 Starter

    引言 上篇文章<天天用SpringBoot,它的自动装配原理却说不出来>我们有说springBoot的自动装配怎么实现的(建议最好先看下篇文章,因为前后有关系),这篇文章的话我们就自己来实 ...

  6. 手把手教你如何优雅的使用Aop记录带参数的复杂Web接口日志

    前言 不久前,因为需求的原因,需要实现一个操作日志.几乎每一个接口被调用后,都要记录一条跟这个参数挂钩的特定的日志到数据库.举个例子,就比如禁言操作,日志中需要记录因为什么禁言,被禁言的人的id和各种 ...

  7. 第一节:学会Java前提-手把手教你配置JDK环境变量

    前言 大家好,今天写一遍学会Java前提-手把手教你配置JDK环境变量的概述,希望你们喜欢 下载地址 下载jdk,和eclipse就比较简单了,提供JDK 9 地址: http://www.oracl ...

  8. 新书上线:《Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统》,欢迎大家买回去垫椅子垫桌脚

    新书上线 大家好,笔者的新书<Spring Boot+Spring Cloud+Vue+Element项目实战:手把手教你开发权限管理系统>已上线,此书内容充实.材质优良,乃家中必备垫桌脚 ...

  9. 手把手教你使用VUE+SpringMVC+Spring+Mybatis+Maven构建属于你自己的电商系统之vue后台前端框架搭建——猿实战01

            猿实战是一个原创系列文章,通过实战的方式,采用前后端分离的技术结合SpringMVC Spring Mybatis,手把手教你撸一个完整的电商系统,跟着教程走下来,变身猿人找到工作不是 ...

随机推荐

  1. str 转 md5

    @interface NSString (MD5) + (NSString *)md5To32bit:(NSString *)str; @end @implementation NSString (M ...

  2. each遍历

    <script> $(function () { $.each([52, 97], function(index, value) { alert(index + ': ' + value) ...

  3. Zookeeper系列2 原生API 以及核心特性watcher

    原生API 增删改查询 public class ZkBaseTest { static final String CONNECT_ADDR = "192.168.0.120"; ...

  4. delphi 中OutputDebugString 函数的妙用(转载)

    原文地址 https://www.peganza.com/delphi-and-outputdebugstring.html Ever wanted to monitor your Delphi ap ...

  5. springboot 初始化 web 项目 启动报错。。。一直解决不了

    1. 一个简单的SpringBoot项目,启动时报错信息: ERROR 18688 --- [cat-startStop-1] org.apache.catalina.core.ContainerBa ...

  6. 2019.02.21 bzoj5317: [Jsoi2018]部落战争(凸包+Minkowski和)

    传送门 题意:qqq次询问把一个凸包整体加一个向量(x,y)(x,y)(x,y)之后是否与另外一个凸包相交. 思路:转化一下发现只要会求A+B={v⃗=a⃗+b⃗∣a⃗∈A,b⃗∈B}A+B=\{\v ...

  7. C程序编程规范一

    和身边一些学弟们接触发现他们的编程习惯不是太好,对一些基本的规范不重视,今天有时间写一些基本的规范给一些刚入门的新手们,高手可忽略. 首先做项目来说需要建立工程,一般需要几个到几百个上上千个C文件,这 ...

  8. Alpha冲刺-(9/10)

    Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 进一步优化代码,结合自己负责的部分修 ...

  9. 轮播图js编写

    //面向对象 function Left() { this.index = 0; this.lefthover = $('#left-content'); this.listenhover(); th ...

  10. yum-内网yum源服务器配置(CentOS6.5)

    一.安装apache服务1.安装httpd服务 yum -y install httpd (纯内网用rpm包安装也可以) 2.启动httpd服务 service httpd start 二.挂载完整的 ...