java动态代理【一】
生活随笔
收集整理的這篇文章主要介紹了
java动态代理【一】
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
java動(dòng)態(tài)代理的定義:為其他目標(biāo)類的方法增加切面的邏輯,即在執(zhí)行目標(biāo)類方法的時(shí)候,先去執(zhí)行一段如校驗(yàn)檢測(cè)的邏輯代碼。java通俗一點(diǎn)就是生成一個(gè)繼承目標(biāo)類的子類,并在每個(gè)調(diào)用方法都添加一段邏輯。
應(yīng)用場(chǎng)景:當(dāng)我們從別的項(xiàng)目遷移過來的代碼進(jìn)行修改的時(shí)候,如果有一個(gè)需求是當(dāng)要執(zhí)行某個(gè)業(yè)務(wù)類的所有方法前,需要校驗(yàn)其權(quán)限或其他的時(shí)候,如果這個(gè)類是源代碼,我們還可以在類的基礎(chǔ)上對(duì)每個(gè)方法區(qū)更改,但若是打包成jar包的類,若該類有接口還可以實(shí)現(xiàn)一個(gè)代理模式創(chuàng)建一個(gè)代理類,沒有接口就比較麻煩,但接口一旦多起來,那編寫的話也比較麻煩。這時(shí)我們就需要用到動(dòng)態(tài)代理,由jdk動(dòng)態(tài)創(chuàng)建一個(gè)proxy類,我們通過proxy類來調(diào)用目標(biāo)類的方法。
動(dòng)態(tài)代理的實(shí)現(xiàn)有三種方法:1、使用代理模式。1)創(chuàng)建一個(gè)Star(明星)類,其實(shí)現(xiàn)了Speak,Eat接口
? ? ? ?輸出I am Star! 一個(gè)經(jīng)紀(jì)人可以代理不同的明星表述,這在現(xiàn)實(shí)中是符合的。2、使用JDK動(dòng)態(tài)代理(原理是通過映射,動(dòng)態(tài)生成java字節(jié)碼Proxy類)1)同樣以Star類為目標(biāo)類,實(shí)現(xiàn)JDK動(dòng)態(tài)代理需要實(shí)現(xiàn)InvocationHandler接口,如下:
2)測(cè)試類
? ? ? ? 1)CGProxy類,因?yàn)槭欠椒〝r截,故實(shí)現(xiàn)的是MethodInterceptor 接口,下面是一個(gè)簡(jiǎn)單的實(shí)現(xiàn)方法。
下一章探討一下JDK動(dòng)態(tài)代理內(nèi)部的實(shí)現(xiàn)原理。
null
應(yīng)用場(chǎng)景:當(dāng)我們從別的項(xiàng)目遷移過來的代碼進(jìn)行修改的時(shí)候,如果有一個(gè)需求是當(dāng)要執(zhí)行某個(gè)業(yè)務(wù)類的所有方法前,需要校驗(yàn)其權(quán)限或其他的時(shí)候,如果這個(gè)類是源代碼,我們還可以在類的基礎(chǔ)上對(duì)每個(gè)方法區(qū)更改,但若是打包成jar包的類,若該類有接口還可以實(shí)現(xiàn)一個(gè)代理模式創(chuàng)建一個(gè)代理類,沒有接口就比較麻煩,但接口一旦多起來,那編寫的話也比較麻煩。這時(shí)我們就需要用到動(dòng)態(tài)代理,由jdk動(dòng)態(tài)創(chuàng)建一個(gè)proxy類,我們通過proxy類來調(diào)用目標(biāo)類的方法。
動(dòng)態(tài)代理的實(shí)現(xiàn)有三種方法:1、使用代理模式。1)創(chuàng)建一個(gè)Star(明星)類,其實(shí)現(xiàn)了Speak,Eat接口
package cglib;public class Star implements Speak,Eat{@Overridepublic void say() {// TODO Auto-generated method stubSystem.out.println("i am a star");}@Overridepublic void eat() {// TODO Auto-generated method stubSystem.out.println("star eats some fruit");}}
package cglib;//裝飾器模式public class Broker implements Speak{private Speak speak;public Broker(Speak speak){this.speak=speak;}@Overridepublic void say() {// TODO Auto-generated method stubspeak.say();}}
? ? ? ?輸出I am Star! 一個(gè)經(jīng)紀(jì)人可以代理不同的明星表述,這在現(xiàn)實(shí)中是符合的。2、使用JDK動(dòng)態(tài)代理(原理是通過映射,動(dòng)態(tài)生成java字節(jié)碼Proxy類)1)同樣以Star類為目標(biāo)類,實(shí)現(xiàn)JDK動(dòng)態(tài)代理需要實(shí)現(xiàn)InvocationHandler接口,如下:
package cglib;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class JDKDynamicProxy implements InvocationHandler{private Object speak;private JDKDynamicProxy(Object speak){//傳入star對(duì)象this.speak=speak;}//創(chuàng)建一個(gè)靜態(tài)方法,生成代理類,public static Object newProxyInstance(Object speak){System.out.println(JDKDynamicProxy.class.getClassLoader().toString());return Proxy.newProxyInstance(JDKDynamicProxy.class.getClassLoader(),new Class[]{Speak.class,Eat.class}, new JDKDynamicProxy(speak));}//覆蓋InvocationHandler的invoke方法,從參數(shù)可以看出,這個(gè)方法明顯使用了jdk的方法映射來調(diào)用Star的方法,在調(diào)用Star的方法前后,我們都可以增加自己的邏輯代碼@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// TODO Auto-generated method stubSystem.out.println("call the JDKDynamicProxy");return method.invoke(speak, args);}}
2)測(cè)試類
package cglib;import java.lang.reflect.Constructor;public class ProxyTest {public static void main(String[] args) {//裝飾者模式Star star=new Star();Speak b=new Broker(star);b.say();//jdk動(dòng)態(tài)代理模式Speak s=(Speak) JDKDynamicProxy.newProxyInstance(star);s.say();Eat e=(Eat) JDKDynamicProxy.newProxyInstance(star);e.eat();//CGlib動(dòng)態(tài)代理Speak sp=CGProxy.newCGproxyInstance(Star.class);sp.say();}}
? ? ? ? 1)CGProxy類,因?yàn)槭欠椒〝r截,故實(shí)現(xiàn)的是MethodInterceptor 接口,下面是一個(gè)簡(jiǎn)單的實(shí)現(xiàn)方法。
package 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 CGProxy implements MethodInterceptor {public static <T extends Speak> Speak newCGproxyInstance(Class<T> superClass){Enhancer en=new Enhancer();en.setSuperclass(superClass);en.setCallback(new CGProxy());return (Speak)en.create();}@Overridepublic Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {// TODO Auto-generated method stubSystem.out.println("call the CGProxy");return arg3.invokeSuper(arg0, arg2);}}
下一章探討一下JDK動(dòng)態(tài)代理內(nèi)部的實(shí)現(xiàn)原理。
null
轉(zhuǎn)載于:https://www.cnblogs.com/zhenyimo/p/6837321.html
總結(jié)
以上是生活随笔為你收集整理的java动态代理【一】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不孕症的常见治疗措施是什么
- 下一篇: 虚拟函数是否应该被声明仅为private