Java Spring-AOP中的动态代理
2017-11-10 16:17:12
AOP中有两种代理方式,分别是JDK的动态代理和CGLib的动态代理。
- JDK的动态代理
Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。
目标对象必须要实现某种接口。
动态代理类(以下简称为代理类)是一个实现在创建类时在运行时指定的接口列表的类,该类具有下面描述的行为。 代理接口 是代理类实现的一个接口。 代理实例 是代理类的一个实例。 每个代理实例都有一个关联的调用处理程序 对象,它可以实现接口 InvocationHandler。通过其中一个代理接口的代理实例上的方法调用将被指派到实例的调用处理程序的 Invoke 方法,并传递代理实例、识别调用方法的 java.lang.reflect.Method 对象以及包含参数的 Object 类型的数组。调用处理程序以适当的方式处理编码的方法调用,并且它返回的结果将作为代理实例上方法调用的结果返回。
* 常用方法

// 接口
public interface Person {
public void add();
public void delete();
} // 实现类
public class Student implements Person {
@Override
public void add() {
System.out.println("添加操作...");
} @Override
public void delete() {
System.out.println("删除操作...");
}
} // 测试
public class Demo {
public static void main(String[] args) {
Student s= new Student();
// JDK Proxy操作
Person proxy = (Person) Proxy.newProxyInstance(s.getClass().getClassLoader(),
s.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进行身份校验...");
Object res = method.invoke(s, args);
return res;
}
});
proxy.add();
}
}
- CGLib的动态代理
在intercept()函数里,除执行代理类的原因方法,在原有方法前后加入其他需要实现的过程,改变原有方法的参数值,即可以实现对原有类的代理了。这似于AOP中的around advice。
2、使用MethodInterceptor接口实现方法回调
当对代理中所有方法的调用时,都会转向MethodInterceptor类型的拦截(intercept)方法,在拦截方法中再调用底层对象相应的方法。下面我们举个例子,假设你想对目标对象的所有方法调用进行权限的检查,如果没有经过授权,就抛出一个运行时的异常。
net.sf.cglib.proxy.MethodInterceptor接口是最通用的回调(callback)类型,它经常被基于代理的AOP用 来实现拦截(intercept)方法的调用。
MethodInterceptor接口只定义了一个方法:
public Object intercept(Object object, java.lang.reflect.Method method, Object[] args, MethodProxy proxy) throws Throwable;
参数Object object是被代理对象,不会出现死循环的问题。
参数java.lang.reflect.Method method是java.lang.reflect.Method类型的被拦截方法。
参数Object[] args是被被拦截方法的参数。
参数MethodProxy proxy是CGLIB提供的MethodProxy 类型的被拦截方法。
注意:
1、若原方法的参数存在基本类型,则对于第三个参数Object[] args会被转化成类的类型。如原方法的存在一个参数为int,则在intercept方法中,对应的会存在一个Integer类型的参数。
2、若原方法为final方法,则MethodInterceptor接口无法拦截该方法。
// 目标类
public class Student implements Person {
@Override
public void add() {
System.out.println("添加操作...");
} @Override
public void delete() {
System.out.println("删除操作...");
}
} // 实现MethodInterceptor接口的实现类
public class CGLibProxy implements MethodInterceptor {
// 首先得获得该对象
Student s; // 通过构造函数来初始化
CGLibProxy(Student s){
this.s = s;
} // 创建代理
public Student newProxy(){
// 创建CGLib的核心类
Enhancer en = new Enhancer();
// 由于CGLib是通过继承方式实现的,所以需要进行父类的设置
en.setSuperclass(s.getClass());
// 设置回调函数,因为当前类实现了Callback接口的子接口MethodInterceptor
// 所以在回调函数里传的参数是this,并且在每次调用目标对象的方法的时候,其实
// 是在调用intercept方法
en.setCallback(this);
// 返回代理对象
return (Student) en.create();
} @Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("进行权限校验...");
Object res = methodProxy.invokeSuper(o, objects);
return res;
}
} // 测试
public class Demo {
public static void main(String[] args) {
Student s= new Student(); // CGLib的动态代理
CGLibProxy cg = new CGLibProxy(s);
Student p = cg.newProxy();
p.add();
}
}
- 结论:Spring框架,如果类实现了接口,就使用JDK的动态代理生成代理对象,如果这个类没有实现任何接口,使用CGLIB生成代理对象
Java Spring-AOP中的动态代理的更多相关文章
- Spring AOP中的动态代理
0 前言 1 动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2 Spring AOP中的动态代理机制 2.1 ...
- 转:Spring AOP中的动态代理
原文链接:Spring AOP中的动态代理 0 前言 1 动态代理 1.1 JDK动态代理 1.2 CGLIB动态代理 1.2.1 CGLIB的代理用法 1.2.2 CGLIB的过滤功能 2 S ...
- Spring Boot实践——Spring AOP实现之动态代理
Spring AOP 介绍 AOP的介绍可以查看 Spring Boot实践——AOP实现 与AspectJ的静态代理不同,Spring AOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改 ...
- spring---aop(4)---Spring AOP的CGLIB动态代理
写在前面 前面介绍了Spring AOP的JDK动态代理的过程,这一篇文章就要介绍下Spring AOP的Cglib代理过程. CGLib全称为Code Generation Library,是一个强 ...
- Spring AOP实现原理-动态代理
目录 代理模式 静态代理 动态代理 代理模式 我们知道,Spring AOP的主要作用就是不通过修改源代码的方式.将非核心功能代码织入来实现对方法的增强.那么Spring AOP的底层如何实现对方法的 ...
- Spring AOP系列(二) — 动态代理引言
接上一篇Spring AOP系列(一)- 代理模式,本篇来聊聊动态代理. 动态代理与静态代理的区别 要想了解动态代理与静态代理的区别,需要有两个前置知识点:java程序是如何执行的以及类加载机制. j ...
- Spring AOP关于cglib动态代理
一: Spring AOP的默认代理方式是jdk动态代理,还有另外一种代理方式是cglib代理,简单说前者基于接口,后者基于继承,基本思路是将被代理对象的类作为父类,然后创建子类来进行方法的调用,调用 ...
- spring---aop(2)---Spring AOP的JDK动态代理
写在前面 spring 事务是springAOP 的一个实现.我们以分析spring的事务,来分析spring的AOP实现. 基本知识 如果目标方法被spring的事务声明,则执行该目标方法的对象就会 ...
- Spring AOP系列(三) — 动态代理之JDK动态代理
JDK动态代理 JDK动态代理核心是两个类:InvocationHandler和Proxy 举个栗子 为便于理解,首先看一个例子: 希望实现这样一个功能:使用UserService时,只需关注自己的核 ...
- Spring AOP源码分析--代理方式的选择
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 年前写了一个面试突击系列的文章,目前只有redis相关的.在这个系列里,我整理了一些面试题与大家 ...
随机推荐
- sqlserver 2012隐藏查询结果窗口
1, 08r2的时候都是可以用 ctrl+r隐藏的 到了2012就不行了 方法 . 2, 快捷键的设置
- Quartz学习记录
参考资料: 官方网站 Quartz使用总结
- Ora-1157 ora-1110错误解决案例一枚
1.数据库打开报错如下: SQL> alter database open; alter database open * ERROR at line 1: ORA-01157: cannot i ...
- linux dd命令详解及使用案例场景
一.dd命令 dd:用指定大小的块拷贝一个文件,并在拷贝的同时进行指定的转换. 注意:指定数字的地方若以下列字符结尾,则乘以相应的数字:b=512:c=1:k=1024:w=2 参数注释: 1. if ...
- sql_q.format
field_q_insert = 'id, title, number, created,content'sql_q = 'INSERT INTO testquestion ({}) VALUES ( ...
- QQ-AR助人教版小学英语“动”起来
日前,人教数字出版公司与腾讯QQ达成合作,将以小学英语3-6年级8本课本为合作试点,共同推出全国首个可AR识别的课本,在QQ-AR的帮助下,课本也能“动”起来,更加生动立体地展现在孩子眼前,让学习变得 ...
- [Axiom 3D]1.初识Axiom
1. 简介 The Axiom 3D Rendering Engine is a fully object oriented 3D graphics engine using C# and the . ...
- Java基础知识 Set
在Java中使用Set,可以方便地将需要的类型以集合类型保存在一个变量中.主要应用在显示列表.Set是一个不包含重复元素的 collection. 更确切地讲,set 不包含满足 e1.equals( ...
- 两个栈实现队列&两个栈实现队列
为说明思想,假设队列.栈都很大,不会出现满的情况. 1. 两个栈实现队列 //前提已知: struct Stack { int top; //栈顶指针 int stacksize;//栈的大小 int ...
- WCF标准绑定以及传输协议与编码格式
WCF 定义了9 种标准绑定: 基本绑定(Basic Binding) 由BasicHttpBinding类提供.基本绑定能够将WCF服务公开为旧的ASMX Web服务,使得旧的客户端能够与新的服务协 ...