使用AOP的好处
原始代码的写法
既然要通过代码来演示,那必须要有例子,这里我的例子为:
有一个接口Dao有insert、delete、update三个方法,在insert与update被调用的前后,打印调用前的毫秒数与调用后的毫秒数
首先定义一个Dao接口:
public interface Dao {
public void insert();
public void delete();
public void update();
}
然后定义一个实现类DaoImpl:
public class DaoImpl implements Dao { @Override最原始的写法,我要在调用insert()与update()方法前后分别打印时间,就只能定义一个新的类包一层,在调用insert()方法与update()方法前后分别处理一下
public void insert() {
System.out.println("DaoImpl.insert()");
} @Override
public void delete() {
System.out.println("DaoImpl.delete()");
} @Override
public void update() {
System.out.println("DaoImpl.update()");
} }
,新的类我命名为ServiceImpl,其实现为:
public class ServiceImpl {
private Dao dao = new DaoImpl();
public void insert() {
System.out.println("insert()方法开始时间:" + System.currentTimeMillis());
dao.insert();
System.out.println("insert()方法结束时间:" + System.currentTimeMillis());
}
public void delete() {
dao.delete();
}
public void update() {
System.out.println("update()方法开始时间:" + System.currentTimeMillis());
dao.update();
System.out.println("update()方法结束时间:" + System.currentTimeMillis());
}
}
这是最原始的写法,这种写法的缺点也是一目了然:
方法调用前后输出时间的逻辑无法复用,如果有别的地方要增加这段逻辑就得再写一遍
如果Dao有其它实现类,那么必须新增一个类去包装该实现类,这将导致类数量不断膨胀。
使用AOP
最后来看一下使用AOP的方式,首先定义一个时间处理类,我将它命名为TimeHandler:
public class TimeHandler {
public void printTime(ProceedingJoinPoint pjp) {
Signature signature = pjp.getSignature();
if (signature instanceof MethodSignature) {
MethodSignature methodSignature = (MethodSignature)signature;
Method method = methodSignature.getMethod();
System.out.println(method.getName() + "()方法开始时间:" + System.currentTimeMillis());
try {
pjp.proceed();
System.out.println(method.getName() + "()方法结束时间:" + System.currentTimeMillis());
} catch (Throwable e) {
e.printStackTrace();
}
}
}
}
切面方法printTime本身可以不用定义任何的参数,但是有些场景下需要获取调用方法的类、方法签名等信息,此时可以
在printTime方法中定义JointPoint,Spring会自动将参数注入,可以通过JoinPoint获取调用方法的类、方法签名等信息
。由于这里我用的aop:around,要保证方法的调用,这样才能在方法调用前后输出时间,因此不能直接使用JoinPoint,
因为JoinPoint没法保证方法调用。此时可以使用ProceedingJoinPoint,ProceedingPointPoint的proceed()方法可以保
证方法调用,但是要注意一点,ProceedingJoinPoint只能和aop:around搭配,换句话说,如果aop.xml中配置的是aop:before,
然后printTime的方法参数又是ProceedingJoinPoint的话,Spring容器启动将报错。
接着看一下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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<bean id="daoImpl" class="org.xrq.spring.action.aop.DaoImpl" />
<bean id="timeHandler" class="org.xrq.spring.action.aop.TimeHandler" />
<aop:config>
<aop:pointcut id="addAllMethod" expression="execution(* org.xrq.spring.action.aop.Dao.*(..))" />
<aop:aspect id="time" ref="timeHandler">
<aop:before method="printTime" pointcut-ref="addAllMethod" />
<aop:after method="printTime" pointcut-ref="addAllMethod" />
</aop:aspect>
</aop:config>
</beans>
测试代码很简单:
public class AopTest {
@Test
@SuppressWarnings("resource")
public void testAop() {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring/aop.xml");
Dao dao = (Dao)ac.getBean("daoImpl");
dao.insert();
System.out.println("----------分割线----------");
dao.delete();
System.out.println("----------分割线----------");
dao.update();
}
}
到此我总结一下使用AOP的几个优点:
切面的内容可以复用,比如TimeHandler的printTime方法,任何地方需要打印方法执行前的时间与方法执行后的时间,都可以使用TimeHandler的printTime方法
避免使用Proxy、CGLIB生成代理,这方面的工作全部框架去实现,开发者可以专注于切面内容本身
代码与代码之间没有耦合,如果拦截的方法有变化修改配置文件即可。
使用AOP的好处的更多相关文章
- .Net中的AOP系列之构建一个汽车租赁应用
返回<.Net中的AOP>系列学习总目录 本篇目录 开始一个新项目 没有AOP的生活 变更的代价 使用AOP重构 本系列的源码本人已托管于Coding上:点击查看. 本系列的实验环境:VS ...
- [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- C# AOP框架入门
AOP面向切面编程(Aspect Oriented Programming),是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.Spring框架用的核心技术就是AOP,是函数式编程的一 ...
- Spring学习之AOP总结帖
AOP(面向方面编程),也可称为面向切面编程,是一种编程范式,提供从另一个角度来考虑程序结构从而完善面向对象编程(OOP). 在进行 OOP 开发时,都是基于对组件(比如类)进行开发,然后对组件进行组 ...
- springMVC之AOP
AOP(Aspect-Oriented Programming,面向切面编程) 切面(Aepect):横切关注点(跨越应用程序多个模块的功能)被模块化的对象: 通知(Advice):切面必须要完成的工 ...
- Spring学习(二)——Spring中的AOP的初步理解[转]
[前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...
- AOP和IOC理解
在百度上看到一篇很有意思的文章,是对AOP的一种解释,如下:(摘自:百度文库的 AOP和IOC最容易理解的说明(Spring知识小计)): IOC,依赖倒置的意思, 所谓依赖,从程序的角度看,就是比如 ...
- spring(二) AOP之AspectJ框架的使用
前面讲解了spring的特性之一,IOC(控制反转),因为有了IOC,所以我们都不需要自己new对象了,想要什么,spring就给什么.而今天要学习spring的第二个重点,AOP.一篇讲解不完,所以 ...
- JavaScript实现AOP(面向切面编程)
什么是AOP? AOP(面向切面编程)的主要作用是把一些跟核心业务逻辑模块无关的功能抽离出来,这些跟业务逻辑无关的功能通常包括日志统计.安全控制.异常处理等.把这些功能抽离出来之后, 再通过" ...
随机推荐
- bzoj 4835: 遗忘之树 [树形DP]
4835: 遗忘之树 题意:点分治,选标号最小的重心,上一次重心向下一次重心连有向边,求原树方案数. md我真不知道当初比赛时干什么去了...现在一眼秒啊... \(size[v]=\frac{siz ...
- 夏令营讲课内容整理 Day 5.
DP专场.. 动态规划是运筹学的一个分支, 求解决策过程最优化的数学方法. 我们一般把动态规划简称为DP(Dynamic Programming) 1.动态规划的背包问题 有一个容量为m的背包,有 ...
- 【IT人】如何提高阅读源代码的效率
1.最近刚到公司,公司就发一架构代码自己看,看了几天看的想吐,也在网上找了下相关的技巧吧,不是有句话叫做:成功必有方法,失败总是借口! 2.借鉴别人的方法来看看如下: 记得在开源流行之前,我看过的代码 ...
- vue环境搭建与创建第一个vuejs文件
我们在前端学习中,学会了HTML.CSS.JS之后一般会选择学习一些框架,比如Jquery.AngularJs等.这个系列的博文是针对于学习Vue.js的同学展开的. 1.如何简单地使用Vue.js ...
- js 前端图片压缩+ios图片角度旋转
step1:读取选择的图片,并转为base64: function ImgToBase64 (e, fn) { // 图片方向角 //fn为传入的方法函数,在图片操作完成之后执行 var Orient ...
- [SCOI2009][bzoj1025]游戏
[SCOI2009][bzoj1025]游戏 标签: DP 置换 题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1025 题解 很套路的题目 ...
- Python:main函数
什么是函数? 一个程序可以包含多个模块,程序越复杂,包含的模块和功能就越多,模块细分里面包含多个类,类这个概念在任何一门面向对象语言里面都很重要,在类里面最主要的就是包含的函数,函数式实现某一个功能的 ...
- NDK配置debug环境时:Error:FAILURE: Build failed with an exception
Error:FAILURE: Build failed with an exception. * What went wrong: Execution failed for task ':app:ex ...
- JPA数据懒加载LAZY配合事务@Transactional使用(三)
上篇博文<JPA数据懒加载LAZY和实时加载EAGER(二)>讲到,如果使用懒加载来调用关联数据,必须要保证主查询session(数据库连接会话)的生命周期没有结束,否则,你是无法抽取到数 ...
- Python基础——字符串
Python版本:3.6.2 操作系统:Windows 作者:SmallWZQ 在Python中,字符串也是一种数据类型.相比其它数据类型,字符串算是比较复杂的.为何呢?因为字符串不仅包含英文字母 ...