代理

代理主要可以分为:

  • 静态代理
  • 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. arcgis js之点击获取featureLayer中的点

    arcgis js之点击获取featureLayer中的点 代码: this.view.on('click', (evt) => { let layer = this.map.findLayer ...

  2. css样式背景图片设置缩放

    一.背景颜色图片平铺 background-color 背景颜色 background-image 背景图片地址 background-repeat 是否平铺 默认是平铺 background-pos ...

  3. vue覆盖UI组件样式不生效

    检查检查是不是加了scoped 在vue中,我们需要引用子组件,包括ui组件(element.iview). 但是在父组件中添加scoped之后,在父组件中书写子组件的样式是无效果的. 去掉scope ...

  4. java Calendar Date 获取指定日期所在月或年的第一天和最后一天

    一.获取传入日期所在月的第一天 public static Date getFirstDayDateOfMonth(final Date date) { final Calendar cal = Ca ...

  5. SQL学习——IN运算符

    IN的作用 IN运算符允许您在WHERE子句中指定多个值. IN运算符是多个OR条件的简写. IN的语法 SELECT column_name(s) FROM table_name WHERE col ...

  6. sql 随机数系列

    一.把数据库把某个字段更新为随机数 DECLARE @Hour INT DECLARE @Counts INT SET @Hour =DATENAME(HOUR, GETDATE()) ) BEGIN ...

  7. 针对nginx应用场景的配置 知识整理

    本文为转载,原文链接 前言 原本想写整理一篇针对nginx应用场景的相应配置,但发现已经有人整理了,而且写得非常不错,特意转过来 概论 Nginx 是一款面向性能设计的 HTTP 服务器,能反向代理 ...

  8. 深度学习_1_Tensorflow_1

    # 深度学习 # 图像识别,自然语言处理 # 机器学习 深度学习 # 分类:神经网络(简单) 神经网络(深度) # 回归 图像:卷积神经网络 # 自然语言处理:循环神经网络 # cpu:运行操作系统, ...

  9. DOS导出文件夹或文件名

    dir /s /w >a.txt 应用dos导出当前目录下的文件夹名称(包括子目录,但是不包括文件,仅仅导出文件夹) dir /s/b/a:d >a.txt

  10. Django—跨域请求

    同源策略 首先基于安全的原因,浏览器是存在同源策略这个机制的,同源策略阻止从一个源加载的文档或脚本获取或设置另一个源加载的文档的属性. 而如果我们要跳过这个策略,也就是说非要跨域请求,那么就需要通过J ...