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的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...
随机推荐
- javaScript节流与防抖
一.节流(throttle) 用来实现阻止在短时间内重复多次触发同一个函数.主要用途:防止使用脚本循环触发网络请求的函数的恶意行为,确保请求的真实性(当然也包括其他阻止高频触发行为的应用): 实现原理 ...
- 测试clang-format的格式化效果
我自己写的业余框架已告一段落,主体功能已完成,剩下的就是优化.第一个要优化的,就是代码格式.我一直是用编辑器写代码的,从之前的UltraEdit到notepad++到sublime text,再到现在 ...
- 第一章、接口规范之web-api接口
1.什么是Web API接口 通过网络,规定了前后台信息交互规则的url链接,也就是前后台信息交互的媒介 Web API接口和一般的url链接还是有区别的,Web API接口简单概括有下面四大特点 u ...
- CDH5.16.1的kafka集群报错: No broker in ISR for partition [getngo_collect_apm_test,0]
1 详细错误 kafka.common.NoReplicaOnlineException: No broker in ISR for partition [getngo_collect_apm_tes ...
- CDH5.16.1的Hbase1.2的G1参数配置
1 贴一下自己的G1垃圾收集器参数(region server配置了5G内存) -Xmx5g -Xms5g -XX:MaxDirectMemorySize=5g -XX:+UseG1GC -XX:+U ...
- MySQL8.0.17下载与安装
下载环境:Windows 10 下载地址: https://dev.mysql.com/downloads/mysql/ 1.解压压缩包,修改解压目录. 2.在E:\mysql-8.0.17-winx ...
- Form组件 cookie和session
django form组件 1.渲染标签 2.校验数据 3.展示信息 第一步需要一个form类 from django import forms class MyForm(forms.Form): n ...
- VMware无法连接MKS:套接字连接尝试次数太多解决
粘贴自:https://jingyan.baidu.com/article/425e69e61eb578be15fc16ae.html VMware在开启虚拟机的时候,突然弹出[无法连接MKS:套接字 ...
- E - GCD HDU - 2588
The greatest common divisor GCD(a,b) of two positive integers a and b,sometimes written (a,b),is the ...
- 挺棒的七个Python图形应用GUI开发框架
作为Pyhon开发者,你迟早都会碰到图形用户界面(GUI)应用开发任务,目前市场上有大量Python GUI开发框架可供选择,Python wiki GUI programming给出了超过30个跨平 ...