静态代理

静态代理代码

package com.interview.proxy;import com.sun.org.apache.bcel.internal.generic.NEW;/*** 静态代理* @author 大都督* @create 2020/5/17*/
public class StaticProxy {// 代理和实际对象共同的接口static interface IService{public void sayHello();}// 实际对象static class RealService implements IService{@Overridepublic void sayHello() {System.out.println("hello");}}// 代理static class TraceProxy implements IService{private IService realService;public TraceProxy(IService realService) {this.realService = realService;}@Overridepublic void sayHello() {System.out.println("entering sayHello");this.realService.sayHello();System.out.println("leaving sayHello");}}public static void main(String[] args) {IService realService = new RealService();IService proxyService = new TraceProxy(realService);proxyService.sayHello();}
}

在静态代理中,代理类是直接定义在代码中的,在动态代理中,代理类是动态生成的

动态代理

动态代理是一种强大的功能,它可以在运行时动态创建一个类,实现一个或多个接口,可以在不修改原有类的基础上动态为通过该类获取的对象添加方法、修改行为。

动态代理是实现面向切面的编程AOP(Aspect Oriented Programming)的基础。

动态代理有两种实现方式:
一种是Java SDK提供的;
另外一种是第三方库(如cglib)提供的;

使用Java SDK实现动态代理示例

package com.interview.proxy;import java.lang.reflect.*;/*** Java SDK实现动态代理* @author 大都督* @create 2020/5/17*/
public class JDKDynamicProxy {static interface IService {public void sayHello();}static class RealService implements IService {@Overridepublic void sayHello() {System.out.println("hello");}}static class SimpleInvocationHandler implements InvocationHandler{// 被代理的对象private Object realObj;public SimpleInvocationHandler(Object realObj) {this.realObj = realObj;}/*** 处理所有接口的调用* @param proxy 代理对象本身* @param method 正在被调用的方法* @param args 方法的参数* @return* @throws Throwable*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("entering " + method.getName());Object result = method.invoke(realObj, args);System.out.println("leaving " + method.getName());return result;}}public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {IService realService = new RealService();// 创建代理对象
//        IService proxyService = (IService) Proxy.newProxyInstance(
//                IService.class.getClassLoader(),
//                new Class<? >[] {IService.class},
//                new SimpleInvocationHandler(realService)
//        );// 通过Proxy.getProxyClass创建代理类定义,类定义会被缓存;Class<?> proxyCls = Proxy.getProxyClass(IService.class.getClassLoader(), new Class<?>[]{IService.class});// 获取代理类的构造方法,构造方法有一个InvocationHandler类型的参数;Constructor<?> ctor = proxyCls.getConstructor(new Class<?>[]{InvocationHandler.class});// 创建InvocationHandler对象,创建代理类对象。InvocationHandler handler = new SimpleInvocationHandler((realService));IService proxyService = (IService)ctor.newInstance(handler);proxyService.sayHello();}
}

Java SDK动态代理的局限在于,它只能为接口创建代理,返回的代理对象也只能转换到某个接口类型

cglib动态代理

package com.interview.proxy;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;/*** cglib动态代理* @author 大都督* @create 2020/5/17*/
public class CGLibDynamicProxy {// 被代理的类static class RealService {public void sayHello() {System.out.println("hello");}}static class SimpleInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("entering " + method.getName());Object result = proxy.invokeSuper(object, args);System.out.println("leaving " + method.getName());return result;}}// 生成代理对象private static <T> T getProxy(Class<T> cls) {Enhancer enhancer = new Enhancer();enhancer.setSuperclass(cls);enhancer.setCallback(new SimpleInterceptor());return (T) enhancer.create();}public static void main(String[] args) {RealService proxyService = getProxy(RealService.class);proxyService.sayHello();}
}

cglib的实现机制与Java SDK不同,它是通过继承实现的,它也是动态创建了一个类,但这个类的父类是被代理的类,代理类重写了父类的所有public非final方法,改为调用Callback中的相关方法

Java SDK代理与cglib代理比较

Java SDK代理面向的是一组接口,它为这些接口动态创建了一个实现类。接口的具体实现逻辑是通过自定义的InvocationHandler实现的,这个实现是自定义的,也就是说,其背后都不一定有真正被代理的对象,也可能有多个实际对象,根据情况动态选择。cglib代理面向的是一个具体的类,它动态创建了一个新类,继承了该类,重写了其方法。

从代理的角度看,Java SDK代理的是对象,需要先有一个实际对象,自定义的InvocationHandler引用该对象,然后创建一个代理类和代理对象,客户端访问的是代理对象,代理对象最后再调用实际对象的方法;cglib代理的是类,创建的对象只有一个。

如果目的都是为一个类的方法增强功能,Java SDK要求该类必须有接口,且只能处理接口中的方法,cglib没有这个限制。

Java代理(proxy)相关推荐

  1. Java 代理(proxy)模式

    代理模式(Proxy Pattern) 代理模式是常用的Java 设计模式,它的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代 ...

  2. Java设计模式-Proxy代理模式

    问题分析: 什么是代理模式呢?其实我们在生活中并不少见.对于程序员来说最常接触的莫过于代理上网了,连接大力服务器地址,就可以访问网络. 还有每天吃饭赶进度是常事,叫公司的同事帮忙带饭也是一种代理:如果 ...

  3. Java代理设计模式(Proxy)的四种具体实现:静态代理和动态代理

    面试问题:Java里的代理设计模式(Proxy Design Pattern)一共有几种实现方式?这个题目很像孔乙己问"茴香豆的茴字有哪几种写法?" 所谓代理模式,是指客户端(Cl ...

  4. Java代理设计模式(Proxy)的具体实现:静态代理和动态代理

    Java代理设计模式(Proxy)的具体实现:静态代理和动态代理 实现方式一:静态代理 静态代理方式的优点 静态代理方式的缺点 Java动态代理实现方式一:InvocationHandler Java ...

  5. Java二十三种设计模式 之代理(proxy)

    Java二十三种设计模式 之代理(proxy) 今天我们学习一下静态代理和动态代理 我们来看代码(写一个坦克运行了多少时间): 第一种方法: public calss Tank implements ...

  6. 【java】深入分析Java反射-动态代理 proxy

    1.概述 转载:深入分析Java反射(四)-动态代理 [Java]Java 反射机制浅析 [Java]java代理 静态代理 动态代理 proxy [java]静态代理 proxy 2.动态代理的简介 ...

  7. [Java] 代理模式 Proxy Mode

    [Java] 代理模式 Proxy Mode 文章目录 [Java] 代理模式 Proxy Mode 1. 代理思想 2.java.lang.reflect.Proxy类 2.1 利用反射创建prox ...

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

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

  9. 动态代理proxy与CGLib的区别

    转载自 动态代理proxy与CGLib的区别 昨天被人问及动态代理与CGlib的区别,赶紧回顾一下: 什么是代理? 静态代理与动态代理 静态代理实例 JDK动态代理实例 CGLib 简介 CGLib ...

  10. java代理通俗简单解析

    1         代理 1.1            代理的概念和作用 代理的概念很好理解,就像黄牛代替票务公司给你提供票,经纪人代理艺人和别人谈合作.Java的代理是指实现类作为代理类的属性对象, ...

最新文章

  1. 获取成员函数地址及获取函数地址
  2. 二维数组常用的赋值方式
  3. Thinkphp 数据库配置参数
  4. srt编辑的文件在linux显示乱码,解决看本地视频srt字幕乱码问题教程-srt文件
  5. 蘑菇街撸掉80%研发岗,产品竟然裁到只剩2个人?
  6. 领域驱动设计(DDD)的实践经验分享之持久化透明
  7. 【Tensorflow2】语义分割实战1---斑马线识别
  8. 常见的直流稳压电源电容有哪些?及其详细介绍
  9. 计算机网络——集线器与交换机
  10. codeforces-379C. New Year Ratings Change
  11. AR客户对账单(上月欠款)
  12. git 创建新分支并关联远程分支_git 把远程分支拿到本地,并建立关联关系track | 学步园...
  13. Hive数据库创建表
  14. hdu 6411 带劲的and和(并查集、位运算)
  15. 计算机网络并行传输和串行传输,并行传输和串行传输的区别是什么
  16. 软件开发项目风险管理的几点体会
  17. 诊断CAPL自动化(2)—— 封装了诊断发送的通用CAPL函数库
  18. linux 视频教程 韦山东,韦东山 linux 设备树详解
  19. Android自定义控件----继承ViewGroup侧滑菜单5,抽屉式侧滑,QQ5.0效果(完结)
  20. linux单进程最大内存,限制单个Linux进程的内存使用量

热门文章

  1. 15个最佳电子商务Android应用模板
  2. 盘点丨12款数据库建模工具特点,总有一款适合你!
  3. 【老生谈算法】matlab实现K均值聚类算法——K均值聚类算法
  4. worder字体网页字体对照表
  5. SOP 封装 和 SOIC 封装的区别——细微差别,可以混用
  6. 【机器学习】 - 决策树(西瓜数据集)
  7. 5、传输介质——大对数线缆
  8. 联想开机启动项按哪个_联想笔记本进bios按什么键
  9. vs2013_update5下载链接(请使用迅雷下载)
  10. nifi 安装 使用案例