java的动态代理如何实现

这篇具有很好参考价值的文章主要介绍了java的动态代理如何实现。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. JdkProxy

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

  1. 接口UserInterface.java
public interface UserService {
	String getUserName(String userCde);
}
  1. 原始实现类:UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
	@Override
	public 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() { //动态代理实现类
                    @Override
                    public 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");
    }
}

java的动态代理如何实现,java,开发语言

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

二. Cglib动态代理

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

  1. 原始类UseServiceImpl.java
public class UserServiceImpl implements UserSerice {
	@Override
	public 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/");
        // 设置父类:UserServiceImpl
        enhancer.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 命令进行编译文章来源地址https://www.toymoban.com/news/detail-706377.html

  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

到了这里,关于java的动态代理如何实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中动态代理的实现方式

    动态代理(Dynamic Proxy)是一种在运行时创建代理对象的机制,它允许我们在不事先知道具体类型的情况下,通过代理对象来调用目标对象的方法。 动态代理通常使用在面向对象编程中的AOP(面向切面编程)中,用于在目标对象的方法执行前后,添加一些额外的逻辑(如日志

    2024年02月15日
    浏览(41)
  • 【Java】JDK动态代理实现原理

    代理模式 代理模式一般包含三个角色: Subject :主题对象,一般是一个接口,定义一些业务相关的基本方法。 RealSubject :具体的主题对象实现类,它会实现Subject接口中的方法。 Proxy :代理对象,里面包含一个RealSubject的引用,外部会通过这个代理对象,来实现RealSubject中方

    2024年02月08日
    浏览(42)
  • 【代理设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

    代理模式(Proxy Pattern)是一种结构型设计模式,用一个类来代理另一个类或几个类的功能。 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。 延迟初始化(虚拟代理)。如果你有一个偶尔使用的重量级服务对象,一直保持该对象运行会消耗系统资源

    2023年04月25日
    浏览(89)
  • java中的静态代理、jdk动态代理以及CGLIB 动态代理

    代理模式是一种比较好理解的设计模式。简单来说就是 我们使用代理对象来代替对真实对象(real object)的访问,这样就可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能 那以下文章主要谈三种代理模式, 分别是静态代理,jdk的动态代理,cglib的动

    2024年02月11日
    浏览(44)
  • Java代理模式——静态代理与动态代理

    代理模式允许你为其他对象提供一个代理,以控制对这个对象的访问。代理模式在不改变实际对象的情况下,可以在访问对象时添加额外的功能。 可以理解为代理模式为被代理对象创造了一个替身,调用者可以通过这个替身去实现这个被代理对象的功能,这个替身也可以为被

    2024年02月13日
    浏览(47)
  • 【C语言】动态内存管理基础知识——动态通讯录,如何实现通讯录容量的动态化

    动态内存管理的函数有:malloc,calloc,ralloc,free,本文讲解动态内存函数和使用,如何进行动态内存管理,实现通讯录联系人容量的动态化,对常见动态内存错误进行总结。                           ✨  猪巴戒 :个人主页✨                 所属专栏 :《C语言进阶》

    2024年02月04日
    浏览(68)
  • 动态代理专线IP怎么设置?动态代理IP如何保护在线安全?

    动态代理专线IP和动态代理IP都是网络技术中的重要概念,它们能够帮助用户保护在线安全和提供更稳定的网络连接。但是,很多用户对于如何设置动态代理专线IP和如何使用动态代理IP来保护在线安全并不清楚。下面,我们将详细介绍动态代理专线IP和动态代理IP的设置方法以

    2024年02月04日
    浏览(56)
  • Java中的代理模式(二)JDK动态代理

    大家好👋,我是极客涛😎,上一篇中我们对代理模式有两大类,静态代理和动态代理,对于静态代理相信大家都信手拈来。对于动态代理还有两种实现,一种是java原生的Jdk代理,一种是Cglib方式。因为涉及到源码解读,所以我也将分两期完成,本期主要讲讲JDK动态代理的实

    2024年01月22日
    浏览(42)
  • Java代理之jdk动态代理+应用场景实战

    本文将先介绍jdk动态代理的基本用法,并对其原理和注意事项予以说明。之后将以两个最常见的应用场景为例,进行代码实操。这两个应用场景分别是 拦截器 和 声明性接口 ,它们在许多开发框架中广泛使用。比如在spring和mybatis中均使用了拦截器模式,在mybatis中还利用动态

    2023年04月10日
    浏览(44)
  • 【Java学习笔记】 动态代理

    1、什么是动态代理? 前面已经提到了,动态代理就是【在内存】中动态生成【字节码代理类】的技术。(虽然不需要开发者书写,但是在内存层面依然存在该代理对象】 优点 : 减少了代理类的数量 并且解决了代码复用的问题。 动态代理常见的实现技术包括以下三种 JDK内

    2024年02月04日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包