当前位置: 首页 > news >正文

java的动态代理如何实现

一. JdkProxy

jdkproxy动态代理必须基于接口(interface)实现

  1. 接口UserInterface.java
public interface UserService {String getUserName(String userCde);
}
  1. 原始实现类:UseServiceImpl.java
public class UserServiceImpl implements UserSerice {@Overridepublic String getUserName(String userCde) {System.out.println("the name of " + userCde + "is Austin");return "Austin";}
}
  1. 代理类 :UserProxyFactoryBJdk.java
public class UserProxyFactoryBJdk {public static UserService getUserServiceProxy(UserService origin) {UserService userService = (UserService) Proxy.newProxyInstance(UserService.class.getClassLoader(), new Class[]{UserService.class}, new InvocationHandler() { //动态代理实现类@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("before");Object o = method.invoke(origin, args);System.out.println("after");return o;}});return userService;}public static void main(String[] args) {UserService userService = getUserServiceProxy(new UserServiceImpl());userService.getUserName("123");}
}

执行结果:
before
the name of 123is Austin
after

二. Cglib动态代理

Cglib实现动态代理与JdkProxy不同, 是通过构建继承类实现

  1. 原始类UseServiceImpl.java
public class UserServiceImpl implements UserSerice {@Overridepublic String getUserName(String userCde) {System.out.println("the name of " + userCde + "is Austin");return "Austin";}
}
  1. 代理类 :UserProxyFactoryByCglib.java
public static UserServiceImpl getUserServiceProxy(UserService origin) {Enhancer enhancer = new Enhancer();// 设置debug信息System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/home/aa/dev/testfile/com/austin/meta/cxf/");// 设置父类:UserServiceImplenhancer.setSuperclass(UserServiceImpl.class);//设置代理实现逻辑enhancer.setCallback(new CglibInterCeptor() {public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println("CglibInterCeptor.intercept-before");Object o = proxy.invokeSuper(obj, args);System.out.println("CglibInterCeptor.intercept-after");return o;}});UserServiceImpl userService = ((UserServiceImpl) enhancer.create());return userService;}public static void main(String[] args) {UserService userService = getUserServiceProxy(new UserServiceImpl());userService.getUserName("123");}

  1. 执行结果
    CglibInterCeptor.intercept-before
    the name of 123is Austin
    CglibInterCeptor.intercept-after

三. Java动态编译

通过JavaCompiler动态编译java源文件,并将相应字节码加载到JVM中,其编译底层通过javac -d 命令进行编译

  1. 需要动态编译的类文件
package com.austin.meta.dynamiccompiler;
public class UserServiceImplE extends UserServiceImpl {public UserServiceImplE() {}public String getUserName(String userCde) {System.out.println("before");super.getUserName(userCde);System.out.println("after");return "Austin";}
}
  1. 动态编译类
public class JavaCompilerTest {private static String basePath = "";public static void main(String[] args) throws Exception{System.out.println(ClassLoader.getSystemResource(""));Class<?> userServiceImplE = compiler("UserServiceImplE");UserServiceImpl o = (UserServiceImpl)userServiceImplE.getConstructor(null).newInstance(null);o.getUserName("235");}private static Class<?> getClass(String pakcge, String className) {Class<?> clazz = null;try {clazz = Class.forName(pakcge + "." +className, true, JavaCompilerTest.class.getClassLoader());} catch (ClassNotFoundException e) {e.printStackTrace();}return clazz;}/*** 动态编译java类,并通加载到JVM*/
private static Class<?> compiler(String className) throws IOException {File javaSrcFile = new File(basePath+ "/" + className + ".java");JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);List<String> options = Arrays.asList("-d", ClassLoader.getSystemResource("").toString());JavaCompiler.CompilationTask task = compiler.getTask(null, standardFileManager, null, options, null, standardFileManager.getJavaFileObjects(javaSrcFile));Boolean isCompilerSuccess = task.call();if(!isCompilerSuccess) {return null;}Class<?> clazz = getClass("com.austin.meta.dynamiccompiler", className);return clazz;}
}

  1. 执行结果
    before
    the name of 235is Austin
    after

http://www.lryc.cn/news/162018.html

相关文章:

  • Java--日志管理
  • Pygame中Sprite类的使用2
  • 排队时延与流量强度
  • mysql:如何设计互相关注业务场景
  • AI伦理:科技发展中的人性之声
  • Direct3D光照
  • 编程语言排行榜
  • 基于语雀编辑器的在线文档编辑与查看
  • 开箱报告,Simulink Toolbox库模块使用指南(六)——S-Fuction模块(TLC)
  • Kafka详解
  • rabbitmq+springboot实现幂等性操作
  • ubuntu server 更改时区:上海
  • java 整合 swagger-ui 步骤
  • 介绍两款生成神经网络架构示意图的工具:NN-SVG和PlotNeuralNet
  • iOS IdiotAVplayer实现视频分片缓存
  • SpringBootWeb请求-响应
  • List集合详解
  • 投稿指南【NO.12_8】【极易投中】核心期刊投稿(组合机床与自动化加工技术)
  • 解决git无法上传大文件(50MB)
  • 用递归实现字符串逆序(不使用库函数)
  • 初学python(一)
  • Excel VSTO开发8 -相关控件
  • 华为数据管理——《华为数据之道》
  • Flink CDC 菜鸟教程 -环境篇
  • 【线上问题】linux部署docker应用docker-compose启动报端口占用问题(感觉上没有被占用)
  • 解决虚拟机克隆后IP和命名冲突问题
  • 分享一个python基于数据可视化的智慧社区服务平台源码
  • [密码学入门]凯撒密码
  • 博客之QQ登录功能(一)
  • Redis多机数据库实现