SpringAop与AspectJ
AspectJ
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
spring aop
Spring提供了四种类型的Aop支持
* 基于经典的SpringAOP
* 纯POJO切面
* @ASpectJ注解驱动的切面
* 注入式AspectJ切面(其实与Spring并无多大的关系,这个就是使用AspectJ这个框架实现Aop编程)
基于经典的SpringAop
其使用ProxyFactoryBean创建:
增强(通知)的类型有:
前置通知:org.springframework.aop.MethodBeforeAdvice
后置通知:org.springframework.aop.AfterReturningAdvice
环绕通知:org.aopalliance.intercept.MethodInterceptor
异常通知:org.springframework.aop.ThrowsAdvice
public interface IBookDao {
public int add()
public int delete();
}
public class BookDaoImpl implements IBookDao{
public int add() {
System.out.println("正在添加图书...");
return 0;
}
public int delete() {
System.out.println("正在删除图书...");
return 0;
}
}
//实现了MethodInterceptor的环绕增强类
public class MyAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("Around Advice before method invocation");
Object o = invocation.proceed();
System.out.println("Around Advice after method invocation");
return o;
}
}
//将每一个连接点都当做切点(拦截每一个方法)
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
<bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
<bean id="bookDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="bookDao"/>
<property name="proxyInterfaces" value="com.njust.learning.spring.service.IBookDao"/>
<property name="interceptorNames" value="myadvice"/>
</bean>
使用RegexMethodPointcutAdvisor针对某些特定的方法进行拦截增强
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
<bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
<bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
<property name="patterns" value=".*add"/>
<property name="advice" ref="myadvice"/>
</bean>
<!--使用的时候使用这个id,而不是原始的那个id-->
<bean id="bookDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="bookDao"/>
<property name="proxyInterfaces" value="com.njust.learning.spring.service.IBookDao"/>
<property name="interceptorNames" value="rmpAdvisor"/>
</bean>
注意
像上面这样,每定义一个dao都需要定义一个ProxyFactoryBean,显得很麻烦,所以我们引入自动代理,也就是自动创建代理对象
BeanNameAutoProxyCreator
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
<bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
<bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
<property name="patterns" value=".*add"/>
<property name="advice" ref="myadvice"/>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="*Dao"></property>
<property name="interceptorNames" value="rmpAdvisor"></property>
</bean>
DefaultAdvisorAutoProxyCreator
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
<bean id="myadvice" class="com.njust.learning.spring.aop.MyAdvice"></bean>
<bean id="rmpAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<!--patterns,如果有多个指定的值的话,可以使用,隔开,例如value=".*add,.*delete"-->
<property name="patterns" value=".*add"/>
<property name="advice" ref="myadvice"/>
</bean>
<!--根据切面中生成信息生成代理-->
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
纯POJO切面,需要使用XML进行配置
public interface IBookDao {
public int add();
public int delete();
}
public class BookDaoImpl implements IBookDao{
public int add() {
int a = 1/0;
System.out.println("正在添加图书...");
return 0;
}
public int delete() {
System.out.println("正在删除图书...");
return 0;
}
}
public class PojoAdvice {
public void before(){
System.out.println("前置通知");
}
public void after(Object returnval){
System.out.println("后置通知"+",处理后的结果为:"+returnval);
}
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("环绕前置增强...");
Object o = proceedingJoinPoint.proceed();
System.out.println("环绕后置增强...");
return o;
}
public void afterThrowing(Throwable e){
System.out.println("异常通知:"+e.getMessage());
}
}
<bean id="bookDao" class="com.njust.learning.spring.service.BookDaoImpl"></bean>
<bean id="pojoAdvice" class="com.njust.learning.spring.pojoaop.PojoAdvice"></bean>
<aop:config>
<aop:pointcut id="p" expression="execution (* *.add(..))"/>
<aop:aspect ref="pojoAdvice">
<aop:before method="before" pointcut-ref="p"></aop:before>
<!--通过设置returning来将返回值传递给通知-->
<aop:after-returning method="after" pointcut-ref="p" returning="returnval"/>
<aop:around method="around" pointcut-ref="p"/>
<!--通过设置returning来将异常对象传递给通知-->
<aop:after-throwing method="afterThrowing" pointcut-ref="p" throwing="e"/>
</aop:aspect>
</aop:config>
联系
我们借助于Spring Aop的命名空间可以将纯POJO转换为切面,实际上这些POJO只是提供了满足切点的条件时所需要调用的方法,但是,这种技术需要XML进行配置,不能支持注解
所以spring借鉴了AspectJ的切面,以提供注解驱动的AOP,本质上它依然是Spring基于代理的AOP,只是编程模型与AspectJ完全一致,这种风格的好处就是不需要使用XML进行配置
SpringAop与AspectJ的更多相关文章
- SpringAOP和AspectJ
SpringAOP和AspectJ的关系 问题:之前对 SpringAOP和AspectJ的关系感到疑惑,因为曾经在书上看过SpringAOP集成了AspectJ,那么SpringAOP是直接使用了A ...
- springaop\ cglib\ AspectJ
元编程 vs 动态代理 vs isa代理 springaop的底层实现有两种,一种是jdk的动态代理,另一种是cglib,springaop没有用到aspectj,只是借鉴了它并添加了aspectj风 ...
- Spring-AOP和AspectJ的区别和联系
AOP是Spring框架的重要组成部分.目前我所接触的AOP实现框架有Spring AOP还有就是AspectJ(还有另外几种我没有接触过).我们先来说说他们的区别: AspectJ是一个比较牛逼的A ...
- AspectJ教学
这几天看JAVA基础看的有点头疼,决定时不时的换换口味,准备開始调研一些如今流行的技术,于是,開始埋头思考自己知识的盲区(当时,自己的知识盲区茫茫多...),想了几天后,决定要開始研究一下几种技术及实 ...
- SpringAOP+源码解析,切就完事了
本文是对近期学习知识的一个总结,附带源码注释及流程图,如有不足之处,还望评论区批评指正. 目录 一.AOP.SpringAOP.AspectJ的区别 二.AOP关键术语 三.通知的五种类型 四.切入点 ...
- Spring源码系列(三)--spring-aop的基础组件、架构和使用
简介 前面已经讲完 spring-bean( 详见Spring ),这篇博客开始攻克 Spring 的另一个重要模块--spring-aop. spring-aop 可以实现动态代理(底层是使用 JD ...
- 【Spring技术原理】Aspectj和LoadTimeWeaving的动态代理技术实现指南
前提介绍 当我们聊到Spring框架的项目实际开发中,用的强大的功能之一就是(面向切面编程)的这门AOP技术.如果使用得当,它的最大的作用就是侵入性比较少并且简化我们的工作任务(节省大量的重复性编码) ...
- 梳理清楚springAOP,轻松面向切面编程
不知道大家有没有这样的感觉,平时经常说aop,但是对aop中的一些概念还是模糊,总感觉很飘渺,今天来梳理下关于aop的知识. 一.概念 我们知道现在开发都是spring,讲的最多的也是springAO ...
- 使springAOP生效不一定要加@EnableAspectJAutoProxy注解
在上篇文章<springAOP和AspectJ有关系吗?如何使用springAOP面向切面编程>中遗留了一个问题,那就是在springboot中使用springAOP需要加@EnableA ...
随机推荐
- mysql 开启远程访问
# vi /etc/mysql/my.cnf修改 bind-address = 127.0.0.1 为 bind-address = 0.0.0.0 修改完成后重启mysql服务 # sudo / ...
- 对 Kotlin 与 Java 编程语言的思考
从长远来看,排名前10的也基本上是Java.C.C++.Python.C#.VB.PHP.JavaScript.至于Kotlin的排名,11月份在编程语言仅排41名,Ratings仅有0.216%. ...
- 《剑指offer》第十二题(矩阵中的路径)
// 面试题:矩阵中的路径 // 题目:请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有 // 字符的路径.路径可以从矩阵中任意一格开始,每一步可以在矩阵中向左.右. // 上.下移动 ...
- Android 上传大文件
最近工作需要实现使用 Android 手机上传图片的功能, 参考了网络上的很多资料, 不过网络上的代码都仅仅适合上传较小的文件, 当上传较大文件时(我在自己的测试机器上发现是 2M 左右), 就会因为 ...
- 消息/事件, 同步/异步/协程, 并发/并行 协程与状态机 ——从python asyncio引发的集中学习
我比较笨,只看用await asyncio.sleep(x)实现的例子,看再多,也还是不会. 已经在unity3d里用过coroutine了,也知道是“你执行一下,主动让出权限:我执行一下,主动让出权 ...
- TCP三次握手(待细研究)
xu言: 看到一张不错清晰的Tcp三次握手图,收藏 Initiator 发起人 Receiver 接收者 LISTENING 状态xx服务启动后首先处于侦听(LISTENING)状态. ESTAB ...
- English trip -- Phonics 4 元音字母 i
IPA 国际音标(英语:International Phonetic Alphabet [ælfəbet],缩写:IPA),早期又称万国音标 VOWELS [ɪ] [u] [ʌ] [ɒ ...
- devilbox(二):连接数据库
Devilbox的安装在上一篇https://www.cnblogs.com/ermao0423/p/9505653.html中已经记录了,这篇主要记录各种数据库的连接.用户建立.设置密码等 查看do ...
- python-day27--hashlib模块-摘要算法
1.用途: # 文件校验 # 文件是否被改变# 登录密码 #不能解密,但可以“撞库” #加盐 hashlib.md5('nezha'.encode('utf-8')) 2. import hashli ...
- Largest Point (2015沈阳赛区网络赛水题)
Problem Description Given the sequence A with n integers t1,t2,⋯,tn. Given the integral coefficients ...