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的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...
随机推荐
- 兼容各种浏览器的hack写法
1.Firefox @-moz-document url-prefix() { .selector { property: value; } }上面是仅仅被Firefox浏览器识别的写法 具体如:@- ...
- echo打印换行
shell环境中,echo是常用的数据命令,但有的时候,想通过“\n”使输出换行却换不了,这个时候需要增加-e选项: $ echo "Hellow.\nHey man~" Hell ...
- 获取impala下所有的数据库建表语句
方法一: 现在的导出还是有缺陷的,导出的文件中还是存在其他不必要的信息 #!/bin/bash ##获取数据库 databases=$(hive -e "show databases; ex ...
- python解决导入自定义库失败: ModuleNotFoundError: No module named 'MyLib'
python安装目录:...\python_3_6_1_64bit 新建文件:chenyeubai.pth,写入库所在的绝对路径E:\workSpace\my_code\learn\myLib 安装路 ...
- linux centos常用命令
mkdir 创建文件夹 -Z:设置安全上下文,当使用SELinux时有效: -m<目标属性>或--mode<目标属性>建立目录的同时设置目录的权限: -p或--parents ...
- jQuery获取上传文件的名称
//获取文件名称 function getFileName(path) { var pos1 = path.lastIndexOf('/'); var pos2 = path.last ...
- 201777010217-金云馨《面向对象程序设计(java)》第十七周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 140: invalid continuation byte
web阅片系统,遇到dicom文件在文件夹不能正常读取的问题.解决方法如下: def rep7(request): file_path = os.path.dirname(__file__) + re ...
- 设置pycharm环境下python内存
有的时候在pycharm下的python需要加载很大的内存,那我们如何去修改pycharm的环境的内存呢?? 第一个栈内存,第二是堆内存.
- elementUI 上传文件图片大小加了限制后 仍然上传了
https://blog.csdn.net/chanlingmai5374/article/details/80558444 看了这位老哥的说法 在看看文档 才发现自己没认真看文档 <el-u ...