spring AOP详解二
AOP实例(通过Proxy代理模式)
Spring AOP使用纯java实现,不需要专门的编译过程和类装载器,它在运行期间通过代理方式向目标类织入增强代码,它更侧重于提供一种和Spring IoC容器整合的AOP实现,在Spring中,我们可以无缝的将AOP,IoC,AspectJ整合在一起。
Spring AOP使用了两种代理机制:一种是基于JDK的动态代理,一种是基于CGLib的动态代理;
JDK1.3以后,java提供了动态代理技术,允许开发者在运行期间动态的创建接口的代理实例,JDK的动态代理主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler,其中InvocationHandler是一个接口,可以通过实现该接口定义横切逻辑,并通过反射机制调用目标类的代码,动态的将横切逻辑和业务逻辑编织在一起。
下面我们来看一个JDK动态代理的例子:
1.业务接口UserService.java
package spring.aop.demo1;
public interface UserService {
void removeUser(int userId);
}
2.横切逻辑代理监视代码PerformanceMonitor.java

package spring.aop.demo1;
public class MethodPerformance {
private long begin;
private long end;
private String serviceMethod;
public MethodPerformance(String serviceMethod) {
this.serviceMethod = serviceMethod;
this.begin = System.currentTimeMillis();
}
public void printPerformance() {
this.end = System.currentTimeMillis();
long elapse = end - begin;
System.out.println(serviceMethod + "花费" + elapse + "毫秒");
}
}


package spring.aop.demo1;
public class PerformanceMonitor {
// 通过一个ThreadLocal保存调用线程相关的性能监视信息
private static ThreadLocal<MethodPerformance> performanceRecord = new ThreadLocal<MethodPerformance>();
// 启动对一目标方法的性能监视
public static void begin(String method) {
System.out.println("begin monitor...");
MethodPerformance mp = new MethodPerformance(method);
performanceRecord.set(mp);
}
public static void end() {
System.out.println("end monitor...");
MethodPerformance mp = performanceRecord.get();
mp.printPerformance();
}
}

3.横切逻辑代理代码PerformanceHandler.java

package spring.aop.demo1; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class PerformanceHandler implements InvocationHandler { private Object target; public PerformanceHandler(Object target) {
this.target = target;
} @Override
public Object invoke(Object arg0, Method arg1, Object[] arg2)
throws Throwable {
PerformanceMonitor.begin(target.getClass().getName() + "."
+ arg1.getName());
Object obj = arg1.invoke(target, arg2);// 通过反射机制调用目标对象的方法
PerformanceMonitor.end();
return obj;
} }

首先,我们实现InvocationHandler接口,该接口定义了一个invoke方法,proxy最是最终生成的一个代理实例,一般不会用到,参数arg1是被代理目标实例的某个具体的方法,通过它可以发起目标实例方法的反射调用;参数arg2是通过被代理实例某一个方法的入参,在方法反射调用时候使用,通过代理将横切逻辑代码和业务类的代码编织到了一起。
我们在构造函数里通过target传入希望被代理的目标对象,将目标实例产地个method.inoke(),调用目标实例的方法。
4.通过Proxy结合PerformanceHandler创建UserService接口的代理实例:

package spring.aop.demo1;
import java.lang.reflect.Proxy;
public class UserServiceImpl implements UserService {
@Override
public void removeUser(int userId) {
System.out.println("模拟删除用户:" + userId);
try {
Thread.currentThread().sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
// 将目标业务类和横切代码编织到一起
PerformanceHandler handler = new PerformanceHandler(userService);
// 根据编织了目标业务类逻辑和性能监视横切逻辑的InvocationHandler实例创建代理实例
UserService proxy = (UserService) Proxy.newProxyInstance(userService
.getClass().getClassLoader(), userService.getClass()
.getInterfaces(), handler);
proxy.removeUser(3);
}
}

输出:
begin monitor...
模拟删除用户:3
end monitor...
spring.aop.demo1.UserServiceImpl.removeUser花费203毫秒
说明:上面的代码完成业务类代码和横切代码的编制工作,并生成了代理实例,newProxyInstance方法的第一个参数为类加载器,第二个参数为目标类所实现的一组接口,第三个参数是整合了业务逻辑和横切逻辑的编织器对象。使用JDK代理模式有一个限制,即它只能为接口创建代理实例,这一点我们可以从Proxy.newProxyInstance的方法签名中就可以看的很清楚,第二个参数interfaces就是需要代理实例实现的接口列表。
spring AOP详解二的更多相关文章
- Spring Aop 详解二
这是Spring Aop的第二篇,案例代码很详解,可以查看https://gitee.com/haimama/java-study/tree/master/spring-aop-demo. 阅读前,建 ...
- 【转载】Spring AOP详解 、 JDK动态代理、CGLib动态代理
Spring AOP详解 . JDK动态代理.CGLib动态代理 原文地址:https://www.cnblogs.com/kukudelaomao/p/5897893.html AOP是Aspec ...
- Spring AOP详解(转载)所需要的包
上一篇文章中,<Spring Aop详解(转载)>里的代码都可以运行,只是包比较多,中间缺少了几个相应的包,根据报错,几经百度搜索,终于补全了所有包. 截图如下: 在主测试类里面,有人怀疑 ...
- Spring AOP详解及简单应用
Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- 转:Spring AOP详解
转:Spring AOP详解 一.前言 在以前的项目中,很少去关注spring aop的具体实现与理论,只是简单了解了一下什么是aop具体怎么用,看到了一篇博文写得还不错,就转载来学习一下,博文地址: ...
- [Spring学习笔记 5 ] Spring AOP 详解1
知识点回顾:一.IOC容器---DI依赖注入:setter注入(属性注入)/构造子注入/字段注入(注解 )/接口注入 out Spring IOC容器的使用: A.完全使用XML文件来配置容器所要管理 ...
- Spring系列(四):Spring AOP详解
一.AOP是什么 AOP(面向切面编程),可以说是一种编程思想,其中的Spring AOP和AspectJ都是现实了这种编程思想.相对OOP(面向过程编程)来说,提供了另外一种编程方式,对于OOP过程 ...
- Spring Aop 详解一
Aop 是一个编程思想,最初是一个理论,最后落地成了很多的技术实现. 我们写一个系统,都希望尽量少写点儿重复的东西.而很多时候呢,又不得不写一些重复的东西.比如访问某些方法的权限,执行某些方法性能的日 ...
- Spring AOP详解 、 JDK动态代理、CGLib动态代理
AOP是Aspect Oriented Programing的简称,面向切面编程.AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理以及日志记录.AOP将这些分散在各个业务逻辑中的代码 ...
随机推荐
- IOS 屏幕尺寸、分辨率、点之间的相互关系
iOS 设备现有的分辨率如下:iPhone/iPod Touch普通屏 320像素 x 480像素 iPhone 1.3G.3GS,iPod ...
- linux命令之文本查看
vi掌握练习: 英文文档,相同的单词复制粘贴光标移动编辑等操作: cat:显示文件所有内容,小文件查看时使用. 缺点:文件大时不方便查看,文件很大时,会抢占系统资源,会出现命令崩溃. [zyj@loc ...
- Linux中gzip、bzip2、zip、unzip、tar使用介绍
压缩解压缩命令介绍.gz 压缩为gzip文件.bz2 压缩为bzip2文件.tar 打包文件,将多个文件合并成一个目录.tar.gz 先打成tar包,再压缩为gzip文件.tar.bz2 先打成tar ...
- UWP开发:自动生成迷宫&自动寻路算法(3)
+ , + ];//0<=x<=12 0<=y<=24 private static Random Rd = new Random(); 首先声明mazeMap存储数据,声明了 ...
- MFC【exe】工程中的文件大致信息(翻译的)
在工程文件夹中有个readme文件,下面是翻译过来的. ======================================================================== ...
- python基础教程总结15——7 自定义电子公告板
1. Python进行SQLite数据库操作 简单的介绍 SQLite数据库是一款非常小巧的嵌入式开源数据库软件,也就是说没有独立的维护进程,所有的维护都来自于程序本身.它是遵守ACID的关联式数据库 ...
- 在SAP C4C里触发SAP ERP的ATP check和Credit check
在C4C里创建一个新的Sales Quote: 添加三个行项目: 执行action "Request External Pricing"会从ERP更新pricing信息,触发ATP ...
- oracle的clob转换varchar2
time: 2008/02/29 author: skate oracle的clob转换varchar2 今天在做一个表的数据转移的时候,发现要他通过比较clob字段,但大家都知道clob字段是无法比 ...
- BOM属性对象方法
本文原链接:https://cloud.tencent.com/developer/article/1018747 BOM 1.window对象 2.location对象 3.history对象 BO ...
- linux文件查找-find命令
find命令:用于在文件树中查找文件,并作出相应的处理 1.find命令的格式: find pathname -options [-print -exec -ok ...] {}\ 2.find命令的 ...