JDK动态代理
创始人
2024-04-11 05:01:42
0

可以针对一些不特定的类或者一些不特定的方法进行代理 可以在程序运行时动态变化代理规则
代理类在程序运行时才创建代理模式成为动态代理
代理类并不是在Java代码中定义好的 而是在程序运行时根据在Java代码中指示动态生成的

Proxy JDK动态代理 面向接口

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class Test1 {public static void main(String[] args) {Dinner dinner = new Student("张三");//通过动态代理获取一个代理对象 在代理对象中 对某个方法进行增强//ClassLoader loader 被代理的对象的类加载器ClassLoader classLoader = dinner.getClass().getClassLoader();//Class[] interfaces 被代理对象所实现的所有接口Class[] interfaces =dinner.getClass().getInterfaces();//InvocationHandler h 执行处理器对象 专门用于定义增强的规则InvocationHandler handler = new InvocationHandler(){//invoke 当我们让代理对象调用任何方法时 都会触发invoke方法的执行public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//Object proxy 代理对象//Method method 被代理的方法//Object[] args 被代理方法运行时实参Object res = null;if(method.getName().equals("eat")){System.out.println("饭前洗手");//让原有的eat方法去运行res = method.invoke(dinner,args);System.out.println("饭后刷碗");}else{//如果是其他方法 正常执行res = method.invoke(dinner,args);}return null;}};Dinner dinnerProxy = (Dinner)Proxy.newProxyInstance(classLoader,interfaces,handler);//dinnerProxy.eat("包子");dinnerProxy.eat("包子");}
}interface Dinner {void eat(String foodName);void drink();
}class Person implements Dinner{private String name;public Person(String name) {this.name = name;}@Overridepublic void eat(String foodName) {System.out.println(name + "正在吃" + foodName);}@Overridepublic void drink() {}
}class Student implements Dinner{private String name;public Student(String name) {this.name = name;}@Overridepublic void eat(String foodName) {System.out.println(name + "正在食堂吃" + foodName);}@Overridepublic void drink() {System.out.println(name + "正在喝可乐");}
}

1.在不修改原有代码的 或没有办法修改原有代码的情况下
增强对象功能 使用代理对象代替原来的对象完成功能达到拓展功能的目的
2.JDK Proxy动态代理面向接口的动态代理 一定要有接口和实现类的存在
代理对象增强的是实现类 在实现接口方法重写的方法
代理对象只能增强接口中定义的的方法 类中其他和接口无关的方法无法增强
代理对象只能读取接口中方法上的注解 不能读取到实现类方法的注解

cglib 第三方动态代理 面向父类

在这里插入图片描述

import org.junit.Test;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class Test1 {@Testpublic void testCglib(){Person person = new Person();//获取一个Person代理对象//1.获取一个Enhancer对象Enhancer enhancer = new Enhancer();//2.设置父类的字节码enhancer.setSuperclass(person.getClass());//3.获取MethodIntercepter对象 用于定义增强规则MethodInterceptor methodInterceptor = new MethodInterceptor() {@Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {/** Object o 生成以后的代理对象 personProxy* Method method 父类中原本要执行的方法 Person >>> eat()* Object[] objects 方法在调用时传入的实参数组* MethodProxy methodProxy 子类中重写父类的方法 personProxy >>> eat()*/Object res = null;if (method.getName().equals("eat")){//如果是eat方法 增强并运行System.out.println("饭前洗手");methodProxy.invokeSuper(o,objects);System.out.println("饭后刷碗");}else{//如果是其他方法 不增强运行methodProxy.invokeSuper(o,objects);//子类对象方法执行 默认调用父类对应被重写的方法}return res;}};//4.设置回调方法enhancer.setCallback(methodInterceptor);//5.获得methodInterceptorPerson personProxy = (Person) enhancer.create();//6.使用代理对象完成功能personProxy.eat("包子");}class Person {private String name;public Person() {}public void eat(String foodName) {System.out.println("张三" + "正在吃" + foodName);}}
}

上一篇:链表

下一篇:CRDB-事务层知识点

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...