Spring 基于 AspectJ 的 AOP 开发
Spring 基于 AspectJ 的 AOP 开发
在 Spring 的 aop 代理方式中, AspectJ 才是主流。
1. AspectJ 简介
- AspectJ 是一个基于 java 语言的 AOP 框架
- Spring 2.0 后新增了对 AspectJ 切点表达式支持
- @AspectJ 是 AspectJ1.5 新增功能,通过 JDK5注解技术,允许直接在 Bean 类中定义切面
- 新版本Spring 框架,建议使用 AspectJ 方式来开发 AOP
- 使用 AspectJ 需要导入 Spring AOP 和 AspectJ 相关 jar 包
spring-aop-4.2.4.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-4.2.4.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
2. 注解开发:环境准备
<?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 -->
</beans>
3. @Aspect 提供不同的通知类型
@Before
前置通知,相当于BeforeAdvice
@AfterReturning
后置通知,相当于AfterReturning
@Around
环绕通知,相当于MethodInterceptor
@After Throwing
异常抛出通知,相当于ThrowAdvice
After
最终通知,不管是否异常,改通知都会执行DeclareParents
引介通知,相当于IntroductionInterceptor
(不要求掌握)
a. @Before 前置通知
可以在方法中传入 JoinPoint 对象,用来获得切点信息
// 要增强的代码
@Before(value = "execution(* com.test.aspectJ.demo1.ProductDao.save(..))")
public void before(JoinPoint joinPoint) {
System.out.println("前置通知=========" + joinPoint);
}
b. @AfterReturning 后置通知
通过 returning 属性,可以定义方法返回值,作为参数:
// result 拿到返回值
@AfterReturning(value = "execution(* com.test.aspectJ.demo1.ProductDao.update(..))", returning = "result")
public void afterReturning(Object result) {
System.out.println("后置通知=========="+result);
}
c. @Around 环绕通知
- around 方法的返回值就是目标代理方法执行返回值
- 参数为 ProceedingJoinPoint 可以调用拦截目标方法执行
@Around(value = "execution(* com.test.aspectJ.demo1.ProductDao.delete(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕前通知============");
Object obj = joinPoint.proceed(); //执行目标方法
System.out.println("环绕后通知==========");
return obj;
}
重点:如果不调用 ProceedingJoinPoint 的 proceed 方法,那么目标方法就被拦截了。
d. @AfterThrowing 异常抛出通知
通过设置 throwing 属性,可以设置发生异常对象参数
@AfterThrowing(value = "execution(* com.test.aspectJ.demo1.ProductDao.find(..))", throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("异常抛出通知==========="+e.getMessage());
}
e. After 最终通知
无论是否出现异常,最终通知总是会被执行
@AfterThrowing(value = "execution(* com.test.aspectJ.demo1.ProductDao.findAll(..))", throwing = "e")
public void afterThrowing(Throwable e) {
System.out.println("异常抛出通知==========="+e.getMessage());
}
4. 在通知中通过 value 属性定义切点
通过 execution
函数,可以定义切点的方式切入
语法:
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
例如:
匹配所有类 public 方法:
execution(public * * (..))
匹配指定包下所有类方法:
execution(* com.test.dao.*(.)) //不包含子包
execuiton(* com.test.dao..*(..)) // ..* 表示包,子孙包下所有类
匹配指定类所有方法:
execution(* com.atest.service.UserService.*(..))
匹配实现特定接口所有类方法:
execution(* com.test.doa.GenericDao + .*(..))
匹配所有 save 开头的方法:
execution(* save*(..))
5. 为目标类定义切面类
定义切面类:
@Aspect
public class MyAspectAnno {}
6. 通过 @Pointcut 为切点命名
- 在每个通知内定义切点,会造成工作量大,不易维护,对于重复的切点,可以使用
@Point
进行定义 - 切点方法:
private void
无参数方法,方法名为切点名 - 当通知多个切点时,可以使用 || 进行连接
@Pointcut(value = "execution(* com.test.aspectJ.demo1.ProductDao.save(..))")
private void myPointcut1() {}
基于 AsepctJ 的 XML 方法的 AOP 开发
1. 编写切面类
public class MyAspectXml {
//前置通知
public void before(JoinPoint joinPoint) {
System.out.println("XML方法的前置通知=========="+joinPoint);
}
// 后置通知
public void afterReturning(Object result) {
System.out.println("XML方法的后置通知==========="+result);
}
//环绕通知
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("XML方式的环绕前通知==========");
Object obj = joinPoint.proceed();
System.out.println("XML方式的环绕后通知");
return obj;
}
// 异常抛出通知
public void afterThrowing(Throwable e) {
System.out.println("XML方法的异常抛出通知"+e.getMessage());
}
// 最终通知
public void after() {
System.out.println("XML方法的最终通知");
}
}
2. 完成切面类的配置
<!-- 配置切面类 -->
<bean id="myAspectXml" class="com.test.aspectJ.demo2.MyAspectXml" />
3. 配置 AOP 完成增强
<!-- aop 的相关配置 -->
<aop:config>
<!-- 配置切入点 -->
<aop:pointcut id="pointcut1" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.save())" />
<aop:pointcut id="pointcut2" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.update())" />
<aop:pointcut id="pointcut3" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.delete())" />
<aop:pointcut id="pointcut4" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.findOne())" />
<aop:pointcut id="pointcut5" expression="execution(* com.test.aspectJ.demo2.CustomerDaoImpl.findAll())" />
<!-- 配置AOP的切面 -->
<aop:aspect ref="myAspectXml">
<!-- 配置前置通知 -->
<aop:before method="before" pointcut-ref="pointcut1" />
<!-- 配置后置通知 -->
<aop:after-returning method="afterReturning" pointcut-ref="pointcut2" returning="result" />
<!-- 配置环绕通知 -->
<aop:around method="around" pointcut-ref="pointcut3" />
<!-- 配置异常抛出通知 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="e"/>
<!-- 配置最终通知 -->
<aop:after method="after" pointcut-ref="pointcut5" />
</aop:aspect>
</aop:config>
Spring 基于 AspectJ 的 AOP 开发的更多相关文章
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
- Spring基于AspectJ的AOP的开发——注解
源码:https://gitee.com/kszsa/dchart 一, AspectJ的概述: AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法所以它有一个专 ...
- Spring框架学习09——基于AspectJ的AOP开发
1.基于注解开发AspectJ (1)AspectJ注解 基于注解开发AspectJ要比基于XML配置开发AspectJ便捷许多,所以在实际开发中推荐使用注解方式.关于注解的相关内容如下: @Aspe ...
- Spring基于AspectJ的AOP的开发之AOP的相关术语
1. Joinpoint(连接点) -- 所谓连接点是指那些被拦截到的点.在spring中,这些点指的是方法,因为spring只支持方法类型的连接点(任何一个方法都可以称为连接点) 2. Pointc ...
- 十四 Spring的AOP的基于AspectJ的注解开发
Spring的AOP的基于AspectJ的注解开发 创建项目,引入jar包 编写目标类.切面类 配置目标类.切面类 在注解文件里开启AOP的开发 <?xml version="1.0& ...
- (转)Spring使用AspectJ进行AOP的开发:注解方式
http://blog.csdn.net/yerenyuan_pku/article/details/69790950 Spring使用AspectJ进行AOP的开发:注解方式 之前我已讲过Sprin ...
- Spring整合AspectJ的AOP
学而时习之,不亦说乎! --<论语> 看这一篇之前最好先看前面关于AOP的两篇. http://www.cnblogs.com/z ...
- 利用基于@AspectJ的AOP实现权限控制
一. AOP与@AspectJ AOP 是 Aspect Oriented Programming 的缩写,意思是面向方面的编程.我们在系统开发中可以提取出很多共性的东西作为一个 Aspect,可以理 ...
- Spring_AOP基于AspectJ的注解开发&JDBC的模板使用&事务管理(学习笔记3)
一:AOP基于AspectJ的注解开发 1,简单的实例: 1)引入相应的jar包 2)在配置文件里引入相关约束 <beans xmlns="http://www.springfra ...
随机推荐
- postgresql数据库的 to_date 和 to_timestamp 将 字符串转换为时间格式
数据库中:字符串 转换为 时间格式 二者区别: to_data 转换为 普通的时间格式 to_timestamp 转换可为 时间戳格式出错场景: 比较同一天 日期大小的时候,很容易出错 ...
- redis 用scan 代替keys,hgetAll
转载自:https://blog.csdn.net/w05980598/article/details/80264568 众所周知,当redis中key数量越大,keys 命令执行越慢,而且最重要的会 ...
- Python接口测试-以&连接拼接字典数据(get中url请求数据)
get请求的utl数据是这样的,例如:/banner/findBanner?bannerType=1&_=1556107073181 ''' 1-banner图-banner/findBann ...
- BrowserUtils
import android.content.Context; import android.content.Intent; import android.net.Uri; public class ...
- PHP拼多多模式,砍价免费拿商品算法
我12年开始做网站,对拼多多关注两三年了,一直对他们的拉新模式很感兴趣,下面我对砍价送礼品的算法跟大家分享下. 拼多多砍价免费拿商品有几个核心的东西: 1.需要拉新多人给商品,这个是直接在数据库配 ...
- Python - 二叉树, 堆, headq 模块
二叉树 概念 二叉树是n(n>=0)个结点的有限集合,该集合或者为空集(称为空二叉树), 或者由一个根结点和两棵互不相交的.分别称为根结点的左子树和右子树组成. 特点 每个结点最多有两颗子树,所 ...
- Centos7下使用Ceph-deploy快速部署Ceph分布式存储-操作记录(转)
之前已详细介绍了Ceph分布式存储基础知识,下面简单记录下Centos7使用Ceph-deploy快速部署Ceph环境:1)基本环境 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- Spring Boot AOP Demo
什么是AOP? AOP面向切面,切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性. 实现策略JAVA SE动态代理 ...
- 初识消息中间件之 ==> ActiveMQ
一.消息队列概述 消息(Message)是指在应用间传送的数据.消息可以非常简单,比如只包含文本字符串,也可以更复杂,可能包含嵌入对象. 消息队列(Message Queue)是一种应用间的通信方式, ...
- 高可用安装k8s1.13.0 --不能带cavisor、不能加cni ,带上这两个总是报错,kubelet无法启动
高可用安装k8s1.13.0 --不能带cavisor,总是报错,kubelet无法启动