您的位置 首页 > 德语词汇

proxy是什么意思?用法、例句(动态代理(Proxy))

本篇文章给大家谈谈proxy是什么意思?用法、例句,以及动态代理(Proxy)对应的知识点,文章可能有点长,但是希望大家可以阅读完,增长自己的知识,最重要的是希望对各位有所帮助,可以解决了您的问题,不要忘了收藏本站喔。

由于某些原因需要给某对象提供一个代理以控制对该对象的访问。这时,访问对象不适合或者不能直接引用目标对象,代理对象作为访问对象和目标对象之间的中介。Java中的代理按照代理类生成时机不同又分为静态代理和动态代理。静态代理代理类在编译期就生成,而动态代理代理类则是在Java运行时动态生成。

packagetop.simba1949.proxy.staticState;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:30\n*/\npublicinterfaceSellTicket{\n\nvoidsell();\n}

TrainStation

proxy是什么意思?用法、例句(动态代理(Proxy))

packagetop.simba1949.proxy.staticState;\n\nimportlombok.extern.slf4j.Slf4j;\n\n/**\n*火车站\n*@authoranthony\n*@datetime2023/7/1922:31\n*/\n@Slf4j\npublicclassTrainStationimplementsSellTicket{\n\n@Override\npublicvoidsell(){\nlog.info("火车站卖票");\n}\n}

ProxyTrainStation

packagetop.simba1949.proxy.staticState;\n\nimportlombok.extern.slf4j.Slf4j;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:31\n*/\n@Slf4j\npublicclassProxyTrainStationimplementsSellTicket{\n\n//声明火车站类对象\nprivateTrainStationtrainStation=newTrainStation();\n\n@Override\npublicvoidsell(){\nlog.info("代售点收取服务费");\ntrainStation.sell();\n}\n}

测试

/**\n*静态代理\n*ProxyTrainStation代理了TrainStation类对象,\n*ProxyTrainStation作为访问对象和目标对象的中介,也对sell方法进行了增强\n*/\npublicstaticvoidstaticState(){\nProxyTrainStationproxyTrainStation=newProxyTrainStation();\nproxyTrainStation.sell();\n}动态代理JDK动态代理创建一个接口Subject;创建一个被代理的类RealSubject并实现Subject接口;创建动态代理处理类JdkInvocationHandler,并实现InvocationHandler接口,重写invoke方法,对方法进行业务处理;设置被代理接口并提供获取被被代理接口示例对象的方法;测试;

Subject接口

packagetop.simba1949.proxy.jdk;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:39\n*/\npublicinterfaceSubject{\n\nStringdoSomething();\n}

RealSubject被代理的类

packagetop.simba1949.proxy.jdk;\n\nimportlombok.extern.slf4j.Slf4j;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:40\n*/\n@Slf4j\npublicclassRealSubjectimplementsSubject{\n\n@Override\npublicStringdoSomething(){\nlog.info("RealSubjectdoSomething");\nreturnnull;\n}\n}

JdkInvocationHandler代理处理类

packagetop.simba1949.proxy.jdk;\n\nimportlombok.extern.slf4j.Slf4j;\n\nimportjava.lang.reflect.InvocationHandler;\nimportjava.lang.reflect.Method;\nimportjava.lang.reflect.Proxy;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:40\n*/\n@Slf4j\npublicclassJdkInvocationHandler<T>implementsInvocationHandler{\n\n//被代理的类\nprivateTtarget;\n\npublicJdkInvocationHandler(Tsubject){\nthis.target=subject;\n}\n\n/**\n*获取被代理接口实例对象\n*@return\n*/\npublicTgetProxy(){\n//第一个参数是类加载器,用于加载这个代理类,可以通过目标对象获取类加载器\n//第二个参数是Class数组,里面存放的是待实现的接口信息\n//第三个参数是InvocationHandler实例,代理对象的调用处理程序\nreturn(T)Proxy.newProxyInstance(\ntarget.getClass().getClassLoader(),\ntarget.getClass().getInterfaces(),\nthis);\n}\n\n/**\n*invoke方法\n*@paramproxy动态代理的类实例\n*@parammethod调用的方法\n*@paramargs调用方法的参数\n*@return\n*@throwsThrowable\n*/\n@Override\npublicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{\nlog.info("dosomethingbefore");\n//result是被代理方法的返回值\nObjectresult=method.invoke(target,args);\nlog.info("dosomethingafter");\nreturnresult;\n}\n}

测试

publicstaticvoidjdkProxy(){\n//realSubject被代理的类\nRealSubjectrealSubject=newRealSubject();\nSubjectproxy=newJdkInvocationHandler(realSubject).getProxy();\nproxy.doSomething();\n}cglib动态代理

CGLIB是一个功能强大、高性能的代码生成包。它为没有实现接口的类提供代理,为JDK的动态代理提供了很好的补充。

cglibmaven地址:https://mvnrepository.com/artifact/cglib/cglib引入cglib包

<!--https://mvnrepository.com/artifact/cglib/cglib-->\n<dependency>\n<groupId>cglib</groupId>\n<artifactId>cglib</artifactId>\n<version>3.3.0</version>\n</dependency>

SubjectService被代理类

packagetop.simba1949.proxy.cglib;\n\nimportlombok.extern.slf4j.Slf4j;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:54\n*/\n@Slf4j\npublicclassSubjectService{\n\npublicStringdoSomething(){\nlog.info("SubjectServicedoSomething");\nreturn"SUCCESS";\n}\n}

代理处理类

packagetop.simba1949.proxy.cglib;\n\nimportlombok.extern.slf4j.Slf4j;\nimportnet.sf.cglib.proxy.MethodInterceptor;\nimportnet.sf.cglib.proxy.MethodProxy;\n\nimportjava.lang.reflect.Method;\n\n/**\n*@authoranthony\n*@datetime2023/7/1922:57\n*/\n@Slf4j\npublicclassCglibMethodInterceptorimplementsMethodInterceptor{\n\n/**\n*@paramobj表示增强的对象\n*@parammethod表示被拦截的方法;\n*@paramobjects表示被拦截方法的参数;\n*@parammethodProxy表示要触发父类的方法对象;\n*@return\n*@throwsThrowable\n*/\n@Override\npublicObjectintercept(Objectobj,\nMethodmethod,\nObject[]objects,\nMethodProxymethodProxy)throwsThrowable{\nlog.info("dosomethingbefore");\n//result是返回结果\nObjectresult=methodProxy.invokeSuper(obj,objects);\nlog.info("dosomethingafter");\nreturnresult;\n}\n}

代理工厂类

packagetop.simba1949.proxy.cglib;\n\nimportnet.sf.cglib.proxy.Enhancer;\nimportnet.sf.cglib.proxy.MethodInterceptor;\n\n/**\n*@authoranthony\n*@datetime2023/7/1923:05\n*/\npublicclassCglibProxyFactory{\n\npublicstatic<T>TgetProxyObj(Class<T>targetCls,MethodInterceptormethodInterceptor){\n//通过CGLIB动态代理获取代理对象的过程\nEnhancerenhancer=newEnhancer();\n//设置enhancer对象的父类\nenhancer.setSuperclass(targetCls);\n//设置enhancer的回调对象\nenhancer.setCallback(methodInterceptor);\n//创建代理对象\nreturn(T)enhancer.create();\n}\n}

测试

/**\n*cglib动态代理,通过代理工厂代理\n*/\npublicstaticvoidcglibProxyByFactory(){\n//使用代理工厂\nSubjectServiceproxy=CglibProxyFactory.getProxyObj(SubjectService.class,newCglibMethodInterceptor());\n//通过代理对象调用目标方法\nStringresult=proxy.doSomething();\nlog.info("resultis{}",result);\n}\n\n/**\n*cglib动态代理\n*/\npublicstaticvoidcglibProxy(){\n//通过CGLIB动态代理获取代理对象的过程\nEnhancerenhancer=newEnhancer();\n//设置enhancer对象的父类\nenhancer.setSuperclass(SubjectService.class);\n//设置enhancer的回调对象\nenhancer.setCallback(newCglibMethodInterceptor());\n//创建代理对象\nSubjectServiceproxy=(SubjectService)enhancer.create();\n//通过代理对象调用目标方法\nStringresult=proxy.doSomething();\nlog.info("resultis{}",result);\n}javassist动态代理javassist官网:https://www.javassist.org/javassistmaven仓库地址:https://mvnrepository.com/artifact/org.javassist/javassist

引入javassist依赖包

<!--https://mvnrepository.com/artifact/org.javassist/javassist-->\n<dependency>\n<groupId>org.javassist</groupId>\n<artifactId>javassist</artifactId>\n<version>3.29.2-GA</version>\n</dependency>

SubjectService被代理类

packagetop.simba1949.proxy.javassist;\n\nimportlombok.extern.slf4j.Slf4j;\n\n/**\n*@authoranthony\n*@datetime2023/7/1923:28\n*/\n@Slf4j\npublicclassJavassistSubjectService{\n\npublicStringdoSomething(){\nlog.info("JavassistSubjectServicedoSomething");\nreturn"SUCCESS";\n}\n}

代理处理类

packagetop.simba1949.proxy.javassist;\n\nimportjavassist.util.proxy.MethodHandler;\nimportlombok.extern.slf4j.Slf4j;\n\nimportjava.lang.reflect.Method;\n\n/**\n*@authoranthony\n*@datetime2023/7/1923:29\n*/\n@Slf4j\npublicclassJavassistMethodHandlerimplementsMethodHandler{\n\n/**\n*\n*@paramself代理类的实例\n*@paramthisMethod表示被拦截的方法\n*@paramproceed表示要触发父类的方法对象\n*@paramargs表示被拦截方法的参数;\n*@return\n*@throwsThrowable\n*/\n@Override\npublicObjectinvoke(Objectself,\nMethodthisMethod,\nMethodproceed,\nObject[]args)throwsThrowable{\nlog.info("dosomethingbefore");\n//result是返回结果\nObjectresult=proceed.invoke(self,args);\nlog.info("dosomethingafter");\nreturnresult;\n}\n}

代理工厂

packagetop.simba1949.proxy.javassist;\n\nimportjavassist.util.proxy.MethodHandler;\nimportjavassist.util.proxy.ProxyFactory;\nimportjavassist.util.proxy.ProxyObject;\n\n/**\n*@authoranthony\n*@datetime2023/7/1923:32\n*/\npublicclassJavassistProxyFactory{\n\npublicstatic<T>TgetProxy(Class<T>targetCls,MethodHandlermethodHandler)throwsInstantiationException,IllegalAccessException{\n//创建代理工厂\nProxyFactoryproxyFactory=newProxyFactory();\n//设置代理类的父类,也是被代理类\nproxyFactory.setSuperclass(targetCls);\n//生成动态代理类\nClass<?>aClass=proxyFactory.createClass();\n//创建动态代理类的实例\nObjectproxyInstance=aClass.newInstance();\n//设置动态处理方式\n((ProxyObject)proxyInstance).setHandler(methodHandler);\n\nreturn((T)proxyInstance);\n}\n}

测试

/**\n*javassist动态代理,通过代理工厂代理\n*@throwsInstantiationException\n*@throwsIllegalAccessException\n*/\npublicstaticvoidjavassistProxyByFactory()throwsInstantiationException,IllegalAccessException{\nJavassistSubjectServiceproxy=JavassistProxyFactory.getProxy(JavassistSubjectService.class,newJavassistMethodHandler());\n//执行代理方法\nStringresult=proxy.doSomething();\nlog.info("resultis{}",result);\n}\n\n/**\n*javassist动态代理\n*@throwsInstantiationException\n*@throwsIllegalAccessException\n*/\npublicstaticvoidjavassistProxy()throwsInstantiationException,IllegalAccessException{\n//创建代理工厂\nProxyFactoryproxyFactory=newProxyFactory();\n//设置代理类的父类,也是被代理类\nproxyFactory.setSuperclass(JavassistSubjectService.class);\n//生成动态代理类\nClass<?>aClass=proxyFactory.createClass();\n//创建动态代理类的实例\nObjectproxyInstance=aClass.newInstance();\n//设置动态处理方式\nJavassistMethodHandlerjavassistMethodHandler=newJavassistMethodHandler();\n((ProxyObject)proxyInstance).setHandler(javassistMethodHandler);\n//执行代理方法\nStringresult=((SubjectService)proxyInstance).doSomething();\nlog.info("resultis{}",result);\n}几种代理的对比jdk代理和CGLIB代理

使用cglib实现动态代理,cglib底层采用ASM字节码生成框架,使用字节码技术生成代理类,在JDK1.6之前比使用Java反射效率要高。唯一需要注意的是,cglib不能对声明为final的类或者方法进行代理,因为cglib原理是动态生成被代理类的子类。在JDK1.6、JDK1.7、JDK1.8逐步对JDK动态代理优化之后,在调用次数较少的情况下,JDK代理效率高于cglib代理效率,只有当进行大量调用的时候,JDK1.6和JDK1.7比cglib代理效率低一点,但是到JDK1.8的时候,JDK代理效率高于cglib代理。所以如果有接口使用JDK动态代理,如果没有接口使用cglib代理。

动态代理与静态代理相比较,最大的好处是接口中声明的所有方法都被转移到调用处理器一个集中的方法中处理(InvocationHandler.invoke)。这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。如果接口增加一个方法,静态代理模式除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。而动态代理不会出现该问题。

好了,文章到此结束,希望可以帮助到大家。

本站涵盖的内容、图片、视频等数据,部分未能与原作者取得联系。若涉及版权问题,请及时通知我们并提供相关证明材料,我们将及时予以删除!谢谢大家的理解与支持!

Copyright © 2023