代理

代理主要可以分为:

  • 静态代理
  • 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代理浅述的更多相关文章

  1. 浅谈Java代理二:Cglib动态代理-MethodInterceptor

    浅谈Java代理二:Cglib动态代理-MethodInterceptor CGLib动态代理特点: 使用CGLib实现动态代理,完全不受代理类必须实现接口的限制,而且CGLib底层采用ASM字节码生 ...

  2. 浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance

    浅谈Java代理一:JDK动态代理-Proxy.newProxyInstance java.lang.reflect.Proxy:该类用于动态生成代理类,只需传入目标接口.目标接口的类加载器以及Inv ...

  3. 浅谈java代理模式

    讲解java代理模式 目录 讲解java代理模式 何谓代理模式 静态代理 动态代理 JDK动态代理 CGLIB动态代理 何谓代理模式 代理模式,即Proxy Pattern,23种java常用设计模式 ...

  4. Java代理模式

    java代理模式及动态代理类 1.      代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目 ...

  5. java 代理的三种实现方式

    Java 代理模式有如下几种实现方式: 1.静态代理. 2.JDK动态代理. 3.CGLIB动态代理. 示例,有一个打招呼的接口.分别有两个实现,说hello,和握手.代码如下. 接口: public ...

  6. java代理的深入浅出(二)-CGLIB

    java代理的深入浅出(二)-CGLIB 1.基本原理 CGLIB的原理就是生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法.在子类中拦截所有父类方法的调用,拦截下来交给设置的Me ...

  7. java代理的深入浅出(一)-Proxy

    java代理的深入浅出(一)-Proxy 1.什么是代理 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事 ...

  8. JAVA中浅复制与深复制 - coolmist - ITeye技术网站

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

  9. Java代理(静态/动态 JDK,cglib)

    Java的代理模式是应用非常广泛的设计模式之一,也叫作委托模式,其目的就是为其他的对象提供一个代理以控制对某个对象的访问和使用,代理类负责为委托类预处理消息,过滤消息并转发消息,以及对消息执行后续处理 ...

随机推荐

  1. 使用百度echarts仿雪球分时图(四)

    这章节来收拾一下一些小BUG,顺便把各个小提示信息也补上,分时图也就完成了. 上章节末尾提到的一个bug,就是第一个grid跟第三个grid之间是断开的,折线并没有连在一起,所以先来收拾这个问题.没有 ...

  2. 7.Spring整合Hibernate_1

    Spring 整合 Hibernate 1.Spring指定 database,给下面创建的 SessionFactory用 <!-- !!!!!可以使用 @Resource 将 这个bean对 ...

  3. lua table vs closure

    最近在重构自己写的框架中的定时器模块,需要把回调函数保存起来,大概如下: function timer_mgr:save_timer( this,callback ) return { this = ...

  4. django-bootstrap4|django 加载popper.min.js失败

    1.现象 2.解决过程 2.1.右键查看网页源代码 在浏览器地址栏打开popper.min.js对应的URL,发现无法打开,这个地址是国外的,需要找一个可访问的地址替换. 2.2.找到URL在djan ...

  5. 【2】Git仓库

    一.获取 Git 仓库 初始化仓库 ##基于当前目录初始化仓库 $ git init ##指定demo目录初始化仓库 $ git init demo 克隆现有仓库 ##克隆现有的仓库,默认目录名:li ...

  6. RobHess的SIFT代码解析之RANSAC

    平台:win10 x64 +VS 2015专业版 +opencv-2.4.11 + gtk_-bundle_2.24.10_win32 主要参考:1.代码:RobHess的SIFT源码:SIFT+KD ...

  7. 浅谈nginx简介和应用场景

    简介 nginx是一款轻量级的web服务器,它是由俄罗斯的程序设计师伊戈尔·西索夫所开发. nginx相比于Tomcat性能十分优秀,能够支撑5w的并发连接(而Tomcat只能支撑200-400),并 ...

  8. Matlab---读取 .txt文件

    Matlab读取 .txt文件 这里提供两种方法:1,load()函数.2,importdata()函数. ---------------------------------------------- ...

  9. APP移动测试

    (转自网络) App测试与传统台式机测试相比有一定的复杂性.这些复杂性可以被分类为: 环境(大量的设备,各种移动OSs,适应频繁OSs变化) . 设备(触摸式和非触摸式设备,有限的内存容量,电池耗电量 ...

  10. R的数据结构--矩阵

    矩阵:存放相同类型元素的二维向量 参数解释 matrix(data=NA, nrow = 1, ncol = 1, byrow = FALSE, dimnames = NULL) 参数含义如下: da ...