java代理浅述
代理
代理主要可以分为:
- 静态代理
- JDK自带的动态代理
- Cglib
静态代理
静态代理比较简单,简单来说就是不想直接调用被代理类,通过代理类来实现功能。如下就是使用了静态代理
定义接口
public interface BookFace {
public void addBook();
public void addapple();
}
public class BookFaceImp implements BookFace {
@Override
public void addBook()
{
System.out.println("增加图书方法");
}
@Override
public void addapple()
{
System.out.println("增加苹果");
}
}
public class BookFaceStatic implements BookFace{
private BookFace target;
public BookFaceStatic(BookFace target)
{
this.target=target;
}
@Override
public void addBook() {
System.out.println("美术图书");
target.addBook();
}
@Override
public void addapple() {
System.out.println("红苹果");
target.addapple();
}
}
编写单测:
@Test
public void test3()
{
BookFaceStatic faceStatic=new BookFaceStatic(new BookFaceImp());
faceStatic.addBook();
faceStatic.addapple();
}
输出结果:

上述就是一个简单的静态代理,就是讲需要的被代理类作为参数传入待代理类中。
JDK自带的动态代理
java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。
JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
延续使用上述的接口和接口实现类,核心代码如下:
public class BookFaceProcyJDK implements InvocationHandler {
private Object target;
public Object getProcy(Object target)
{
//获取到是哪个类需要代理
this.target=target;
//getInterfaces()获取代理类的接口
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
}
//重写invoke方法,InvocationHandler中自动会执行
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("批量执行1");
Object result=method.invoke(target,args);
System.out.println("批量执行2");
return result;
}
}
编写单测:
@Test
public void test1()
{
BookFaceImp bookFaceImp=new BookFaceImp();
BookFaceProcyJDK bookFaceProcy=new BookFaceProcyJDK();
BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp);
bookFace.addBook();
bookFace.addapple();
}
输出结果:

采坑:
为什么BookFace bookFace= (BookFaceImp)bookFaceProcy.getProcy(bookFaceImp);
不能这样写???
解释:因为代理时相当于新建了一个BookFaceImp1,要么写成(BookFaceImp1)bookFaceProcy.bind(bookFaceImp)或者使用它的父类BookFace,因为不知道到底生成了一个什么名字的BookFaceImp,所以得使用它的父类BookFace。
(代理生成的BookFaceImp1和BookFaceImp是统一层级的)

Cglib
cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。
CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。
延续使用上述的接口和接口实现类,核心代码如下:
public class BookFaceProcyCglib implements MethodInterceptor {
private Object target;
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("监听开始");
Object result=method.invoke(target,args);
System.out.println("监听结束");
return result;
}
public Object getProcy(Object target)
{
this.target=target;
Enhancer enhancer=new Enhancer();
//设置父类,因为cglib是设置子类
enhancer.setSuperclass(target.getClass());
//设置回调
enhancer.setCallback(this);
return enhancer.create();
}
}
单测:
@Test
public void test2()
{
BookFaceImp bookFaceImp=new BookFaceImp();
BookFaceProcyCglib bookFaceProcy=new BookFaceProcyCglib();
BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp);
bookFace.addBook();
bookFace.addapple();
}
运行结果:

Cglib与jdk自带的动态代理不同是生成的bookFaceImp1的父类是bookFaceImp

所以 BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp)也可以改成 BookFace bookFace= (BookFaceImp)bookFaceProcy.getProcy(bookFaceImp),效果一致
java代理浅述的更多相关文章
- 浅谈Java代理二:Cglib动态代理-MethodInterceptor
浅谈Java代理二:Cglib动态代理-MethodInterceptor CGLib动态代理特点: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生 ...
- 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance
浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...
- 浅谈java代理模式
讲解java代理模式 目录 讲解java代理模式 何谓代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 何谓代理模式 代理模式,即Proxy Pattern,23种java常用设计模式 ...
- Java代理模式
java代理模式及动态代理类 1. 代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...
- java 代理的三种实现方式
Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...
- java代理的深入浅出(二)-CGLIB
java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...
- java代理的深入浅出(一)-Proxy
java代理的深入浅出(一)-Proxy 1.什么是代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事 ...
- JAVA中浅复制与深复制 - coolmist - ITeye技术网站
body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...
- Java代理(静态/动态 JDK,cglib)
Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...
随机推荐
- python中的not的意思
python中的not的意思 在python中,not是逻辑判断,用于布尔值true和false,not true是false,not false是true.以下是not的一些常见用法:(1)当表达式 ...
- oracle to_Char fm 函数
近期在使用oracle to_char函数处理浮点数时发现有坑,这里做个小结: 网上可以找到关于to_char中使用fm9990.0099中的相关解释: 0表示:如果参数(double或者float类 ...
- Win10系统升级更新方式将会更智能
使用Win10系统的你肯定遇到过在工作时开始自动更新而不得不搁置工作的情况,想必你也已经被Win10系统的自动更新折磨不已,不过这种情况将会马上得到改观. 微软现在已经开始寻找更智能的版本升级更新方式 ...
- Delphi 重载方法与重定义方法
- Matlab修改数值格式/精度/小数位数
————————————命令行方法————————————— 直接在命令行中输入以下命令,但该命令不影响数据的存储形式和计算精度,下次还需进行修改. format 默认格式 format short ...
- 菜单项(Menu)的初步认识 以及 多级菜单(SubMenu)的初步认识
MainActivity.class public class MainActivity extends AppCompatActivity { private TextView textView; ...
- vim编辑命令
vi命令 命令模式: yy:复制 光标所在的这一行 4yy:复制 光标所在行开始向下的4行 p: 粘贴 dd:剪切 光标所在的这一行 2dd:剪切 光标所在行 向下 2行 D:从当前的光标开始剪切,一 ...
- libusb_bulk_transfer 异步同步
同步方式 libusb_bulk_transfer(devh, ep_bulk, buf, CAM_BUF_SZ, &len, timeout); 进入libusb研究,发现libusb是采用 ...
- 一些网站后台模板源码分析 Particleground.js 验证码
转: https://blog.csdn.net/bcbobo21cn/article/details/51271750 1 灰色简洁企业后台管理模板 效果: 看下项目结构: 它使用了moderniz ...
- Beego框架POST请求接收JSON数据
原文: https://blog.csdn.net/Aaron_80726/article/details/83870563 ------------------------------------- ...