当前位置:首页 > CN2资讯 > 正文内容

java动态代理和cglib动态代理java 动态代理

20小时前CN2资讯

动态代理应用广泛,Spring,Struts等框架很多功能是通过动态代理,或者进一步封装来实现的。

常见的动态代理模式实现有Java API提供的动态代理和第三方开源类库CGLIB动态代理。

Java API提供的动态代理是基于类反射实现的,用到的类有:

java.lang.reflect.InvocationHandler;

java.lang.reflect.Method;

java.lang.reflect.Proxy;

其实现是通过Proxy类的newProxyInstance()方法产生代理对象。自定义动态代理类需要实现InvocationHandler接口,该接口只有一个invoke()方法。


CGLIB是通过生成java 字节码从而动态的产生代理对象,因此需要字节码解析处理的依赖asm类库,字节码动态生成的代理对象实际上是继承了真实主题类的。这种实现方式需要导入cglib和asm的类库。下面用到的例子是cglib-2.2.2.jar, asm-3.3.1.jar。cglib使用了MethodInterceptor,其中的方法是intercept(),这是拦截的概念,很容易就想到了Struts2的拦截器。

比较之下,Java API提供的动态代理需要面向接口,产生代理对象,因此真实主题实现类必须实现了接口才可以。而CGLIB不需要面向接口,可以代理简单类,但由于动态代理对象是继承真实主题实现类的,因此要求真实主题实现类不能是final的。

下面是实现的例子。

首先,为了看到动态代理可以根据不同类动态产生不同代理的效果,我们新建两个接口,及其实现类。

package leon.aj.dynproxy.target; public interface Hello { public String sayHello(String name); }

实现类:

package leon.aj.dynproxy.target; public class HelloImpl implements Hello { @Override public String sayHello(String name) { String s = "Hello, "+name; System.out.println(this.getClass().getName()+"->"+s); return s; } }

另一接口和实现类:

package leon.aj.dynproxy.target; public interface UserDao { public boolean login(String username,String password); } package leon.aj.dynproxy.target; public class UserDaoImpl implements UserDao { @Override public boolean login(String username, String password) { String user = "("+username+","+password+")"; System.out.println(this.getClass().getName()+"-> processing login:"+user); return true; } }


应用Java API实现的动态代理类:

package leon.aj.dynproxy.java; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; public class JavaDynProxy implements InvocationHandler{ private Object target; public Object getProxyInstance(Object target){ this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("before target method..."); result = method.invoke(target, args); System.out.println("after target method..."); return result; } }

测试:

package leon.aj.dynproxy.java; import leon.aj.dynproxy.target.Hello; import leon.aj.dynproxy.target.HelloImpl; import leon.aj.dynproxy.target.UserDao; import leon.aj.dynproxy.target.UserDaoImpl; public class TestJavaProxy { public static void main(String[] args) { JavaDynProxy proxy = new JavaDynProxy(); Hello hello = (Hello)proxy.getProxyInstance(new HelloImpl()); String s = hello.sayHello("Leon"); System.out.println(s); UserDao userDao = (UserDao) proxy.getProxyInstance(new UserDaoImpl()); userDao.login("Leon", "1234"); System.out.println(userDao.getClass().getName()); } }


下面是采用cglib实现的例子:

package leon.aj.dynproxy.cglib; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; public class CglibProxy implements MethodInterceptor { private Object target; public Object getProxyInstance(Object target) { this.target = target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.target.getClass()); enhancer.setCallback(this); // call back method return enhancer.create(); // create proxy instance } @Override public Object intercept(Object target, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("before target method..."); Object result = proxy.invokeSuper(target, args); System.out.println("after target method..."); return result; } }

测试类:

package leon.aj.dynproxy.cglib; import leon.aj.dynproxy.target.Hello; import leon.aj.dynproxy.target.HelloImpl; import leon.aj.dynproxy.target.UserDaoImpl; public class TestCiglib { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); Hello hello = (Hello) proxy.getProxyInstance(new HelloImpl()); System.out.println(hello.sayHello("Leon")); UserDaoImpl userDao = (UserDaoImpl) proxy.getProxyInstance(new UserDaoImpl()); userDao.login("Leon", "1234"); System.out.println(userDao.getClass().getSuperclass());//看动态代理实例的父类 } }












    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/24155.html

    分享给朋友:

    “java动态代理和cglib动态代理java 动态代理” 的相关文章

    RackNerd IP测评:选择可靠VPS的最佳指南

    在我接触过的众多VPS服务提供商中,RackNerd以其高性价比的特点脱颖而出。作为一家位于美国的公司,RackNerd专注于为用户提供可靠的虚拟私人服务器(VPS)解决方案。在这里,我将和大家分享一些关于RackNerd的重要信息,尤其是它的IP测评,我认为这对想要选择VPS的用户来说至关重要。...

    VPS商家全攻略:选择适合你的虚拟专用服务器

    VPS商家概述 在数字化时代,VPS(虚拟专用服务器)服务逐渐成为企业和个人用户的重要选择。VPS不仅为用户提供了灵活性,而且在性能、控制权和安全性上都优于传统的共享主机。这使它成为许多需要独立环境来运行网站或应用程序的用户的理想解决方案。 选择VPS的用户通常追求更高的稳定性和可靠性。相比于共享主...

    国外离线下载服务比较:如何选择最适合你的工具

    在信息时代,国外离线下载服务成为了许多用户的得力助手。这种服务的主要功能,是让用户在没有网络连接的情况下,也能提前将所需的数据或文件下载到本地或云端存储中。这种方法特别适合那些经常出行或在网络不佳的环境中工作的用户。通过离线下载,用户可以在网络恢复后更快、更方便地访问所需内容。 离线下载的应用非常广...

    台湾VPS:高效、稳定且安全的虚拟专用服务器解决方案

    台湾VPS,即虚拟专用服务器,是一种通过虚拟化技术将物理服务器划分为多个独立服务器的解决方案。这种服务不仅为用户提供独享的资源和灵活的管理权限,还能够提升性能和效率。在我使用台湾VPS的过程中,它让我深刻体会到这一技术的便利与强大。 台湾VPS的独特之处在于其地理位置和网络基础设施。位于东亚的台湾,...

    咸鱼云:高性价比VPS服务解决您的在线需求

    咸鱼云概述 在互联网服务日益发展的今天,咸鱼云(SaltyFish)作为一家新兴的主机商家,自2019年成立以来,逐渐在市场中占据了一席之地。它的出现让许多寻找高性价比VPS服务的用户有了新的选择。咸鱼云专注于基于KVM架构的国外VPS服务,凭借较为稳定的性能和实惠的价格,吸引了不少追求性价比的客户...

    菲律宾用户如何通过VPS提升TikTok访问速度

    在菲律宾使用VPS访问TikTok,这个话题对很多喜欢在TikTok上进行电商活动或内容创作的人来说非常重要。首先,我想谈谈VPS的概念以及它的优势。VPS,全称是虚拟专用服务器,它提供了一种比共享主机更为灵活和高效的解决方案。对于菲律宾的用户来说,通过使用VPS,可以在一定程度上绕过地区限制,更流...