java代理浅述

2024-03-10 02:20
文章标签 java 代理 浅述

本文主要是介绍java代理浅述,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

代理

代理主要可以分为:

  • 静态代理
  • JDK自带的动态代理
  • Cglib

静态代理

静态代理比较简单,简单来说就是不想直接调用被代理类,通过代理类来实现功能。如下就是使用了静态代理

定义接口

public interface BookFace {public void addBook();public void addapple();
}
public class BookFaceImp implements BookFace {@Overridepublic void addBook(){System.out.println("增加图书方法");}@Overridepublic void  addapple(){System.out.println("增加苹果");}}
public class BookFaceStatic implements BookFace{private BookFace target;public  BookFaceStatic(BookFace target){this.target=target;}@Overridepublic void addBook() {System.out.println("美术图书");target.addBook();}@Overridepublic void addapple() {System.out.println("红苹果");target.addapple();}
}

编写单测:

@Testpublic void test3(){BookFaceStatic faceStatic=new BookFaceStatic(new BookFaceImp());faceStatic.addBook();faceStatic.addapple();}

输出结果:

1166661-20190729213955757-1626123578.png

上述就是一个简单的静态代理,就是讲需要的被代理类作为参数传入待代理类中。

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中自动会执行@Overridepublic 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;}
}

编写单测:

   @Testpublic void test1(){BookFaceImp bookFaceImp=new BookFaceImp();BookFaceProcyJDK bookFaceProcy=new BookFaceProcyJDK();BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp);bookFace.addBook();bookFace.addapple();}

输出结果:

1166661-20190729214010793-2048833864.png

采坑:
为什么BookFace bookFace= (BookFaceImp)bookFaceProcy.getProcy(bookFaceImp);
不能这样写???

解释:因为代理时相当于新建了一个BookFaceImp1,要么写成(BookFaceImp1)bookFaceProcy.bind(bookFaceImp)或者使用它的父类BookFace,因为不知道到底生成了一个什么名字的BookFaceImp,所以得使用它的父类BookFace。

(代理生成的BookFaceImp1和BookFaceImp是统一层级的)

1166661-20190729214030315-1536074215.png

Cglib

cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法。

延续使用上述的接口和接口实现类,核心代码如下:

  public class BookFaceProcyCglib implements MethodInterceptor {private Object target;@Overridepublic 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();}
}

单测:

   @Testpublic void test2(){BookFaceImp bookFaceImp=new BookFaceImp();BookFaceProcyCglib bookFaceProcy=new BookFaceProcyCglib();BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp);bookFace.addBook();bookFace.addapple();}

运行结果:
1166661-20190729214047389-438034062.png

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

1166661-20190729214059129-747364043.png
所以 BookFace bookFace= (BookFace)bookFaceProcy.getProcy(bookFaceImp)也可以改成 BookFace bookFace= (BookFaceImp)bookFaceProcy.getProcy(bookFaceImp),效果一致

转载于:https://www.cnblogs.com/lixuan1998/p/11266687.html

这篇关于java代理浅述的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/792697

相关文章

Java编译生成多个.class文件的原理和作用

《Java编译生成多个.class文件的原理和作用》作为一名经验丰富的开发者,在Java项目中执行编译后,可能会发现一个.java源文件有时会产生多个.class文件,从技术实现层面详细剖析这一现象... 目录一、内部类机制与.class文件生成成员内部类(常规内部类)局部内部类(方法内部类)匿名内部类二、

SpringBoot实现数据库读写分离的3种方法小结

《SpringBoot实现数据库读写分离的3种方法小结》为了提高系统的读写性能和可用性,读写分离是一种经典的数据库架构模式,在SpringBoot应用中,有多种方式可以实现数据库读写分离,本文将介绍三... 目录一、数据库读写分离概述二、方案一:基于AbstractRoutingDataSource实现动态

Springboot @Autowired和@Resource的区别解析

《Springboot@Autowired和@Resource的区别解析》@Resource是JDK提供的注解,只是Spring在实现上提供了这个注解的功能支持,本文给大家介绍Springboot@... 目录【一】定义【1】@Autowired【2】@Resource【二】区别【1】包含的属性不同【2】@

springboot循环依赖问题案例代码及解决办法

《springboot循环依赖问题案例代码及解决办法》在SpringBoot中,如果两个或多个Bean之间存在循环依赖(即BeanA依赖BeanB,而BeanB又依赖BeanA),会导致Spring的... 目录1. 什么是循环依赖?2. 循环依赖的场景案例3. 解决循环依赖的常见方法方法 1:使用 @La

Java枚举类实现Key-Value映射的多种实现方式

《Java枚举类实现Key-Value映射的多种实现方式》在Java开发中,枚举(Enum)是一种特殊的类,本文将详细介绍Java枚举类实现key-value映射的多种方式,有需要的小伙伴可以根据需要... 目录前言一、基础实现方式1.1 为枚举添加属性和构造方法二、http://www.cppcns.co

Elasticsearch 在 Java 中的使用教程

《Elasticsearch在Java中的使用教程》Elasticsearch是一个分布式搜索和分析引擎,基于ApacheLucene构建,能够实现实时数据的存储、搜索、和分析,它广泛应用于全文... 目录1. Elasticsearch 简介2. 环境准备2.1 安装 Elasticsearch2.2 J

Java中的String.valueOf()和toString()方法区别小结

《Java中的String.valueOf()和toString()方法区别小结》字符串操作是开发者日常编程任务中不可或缺的一部分,转换为字符串是一种常见需求,其中最常见的就是String.value... 目录String.valueOf()方法方法定义方法实现使用示例使用场景toString()方法方法

Java中List的contains()方法的使用小结

《Java中List的contains()方法的使用小结》List的contains()方法用于检查列表中是否包含指定的元素,借助equals()方法进行判断,下面就来介绍Java中List的c... 目录详细展开1. 方法签名2. 工作原理3. 使用示例4. 注意事项总结结论:List 的 contain

Java实现文件图片的预览和下载功能

《Java实现文件图片的预览和下载功能》这篇文章主要为大家详细介绍了如何使用Java实现文件图片的预览和下载功能,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... Java实现文件(图片)的预览和下载 @ApiOperation("访问文件") @GetMapping("

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis