anno_proxy

自定義注解

定義:注解(Annotation),也叫元數(shù)據(jù)。一種代碼級(jí)別的說明。它是JDK1.5及以后版本引入的一個(gè)特性,與類、接口、枚舉是在同一個(gè)層次。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來對(duì)這些元素進(jìn)行說明,注釋。

開發(fā)步驟

  1. 創(chuàng)建一個(gè)@interface

  2. String value();抽象方法用以接收數(shù)據(jù)

  3. 使用元注解,描述自定義注解

  4. @Target指定注解可以加在哪里
    ElementType.TYPE:可在類和接口上面
    ElementType.METHOD:可方法上
    ElementType.FIELD:可在屬性

  5. @Retention指定注解在什么時(shí)候有用
    RetentionPolicy.RUNTIME:注解保留到運(yùn)行時(shí)
    RetentionPolicy.ClASS:注解保留到Class文件中
    RetentionPolicy.SOURCE:注解保留到j(luò)ava編譯時(shí)期

  6. @Inherited可以被繼承

jdk動(dòng)態(tài)代理

  1. 被代理類必須實(shí)現(xiàn)一個(gè)接口,任意接口
public class Bus implements Runnable{}
  1. 創(chuàng)建一個(gè)類實(shí)現(xiàn)InvocationHandler,該類用來對(duì)象代理對(duì)象進(jìn)行方法的增強(qiáng)
public class TimeInvocation implements InvocationHandler{
    private Object target;//被代理對(duì)象
    public TimeInvocation(Object target){
        this.target=target;
    }
}
  1. 在invoke()方法中調(diào)用被代理對(duì)象的方法,并且添加增強(qiáng)的代碼
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    long time1=System.currentTimeMillis();
        //調(diào)用被代理對(duì)象的方法
    method.invoke(target, args);
    long time2=System.currentTimeMillis();
    System.out.println(time2-time1);
    return null;
}
  1. 通過Proxy.newProxyInstance(ClasLoader, Class, InvovationHandler)創(chuàng)建代理類對(duì)象

  2. 調(diào)用代理對(duì)象的方法

TimeInvocation time=new TimeInvocation(s);
Class<?> clazz=s.getClass();
Runnable s1= (Runnable)Proxy.newProxyInstance(clazz.getClassLoader(), clazz.getInterfaces(), time);
s1.run();

cglib

public class SayHello {  
    public void say(){  
        System.out.println("hello everyone");  
    }  
} 
public class CglibProxy implements MethodInterceptor{  
    private Enhancer enhancer = new Enhancer();  
    public Object getProxy(Class clazz){  
    //設(shè)置需要?jiǎng)?chuàng)建子類的類  
        enhancer.setSuperclass(clazz);  
        enhancer.setCallback(this);  
    //通過字節(jié)碼技術(shù)動(dòng)態(tài)創(chuàng)建子類實(shí)例  
        return enhancer.create();  
    }  
    //實(shí)現(xiàn)MethodInterceptor接口方法  
    public Object intercept(Object obj, Method method, Object[] args,  
        MethodProxy proxy) throws Throwable {  
        System.out.println("前置代理");  
        //通過代理類調(diào)用父類中的方法  
        Object result = proxy.invokeSuper(obj, args);  
        System.out.println("后置代理");  
        return result;  
    }  
}  
public class DoCGLib {  
    public static void main(String[] args) {  
        CglibProxy proxy = new CglibProxy();  
        //通過生成子類的方式創(chuàng)建代理類  
        SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);  
        proxyImp.say();  
    }  
}  

注意: jdk動(dòng)態(tài)代理與cglib的區(qū)別

jdk通實(shí)現(xiàn)接口的方式實(shí)現(xiàn)動(dòng)態(tài)代理 cglib通過繼承的方式實(shí)現(xiàn)動(dòng)態(tài)代理

jdk動(dòng)態(tài)代理與cglib如何選擇? CGLib創(chuàng)建的動(dòng)態(tài)代理對(duì)象性能比JDK創(chuàng)建的動(dòng)態(tài)代理對(duì)象的性能高不少,但是CGLib在創(chuàng)建代理對(duì)象時(shí)所花費(fèi)的時(shí)間卻比JDK多得多,所以對(duì)于單例的對(duì)象,因?yàn)闊o需頻繁創(chuàng)建對(duì)象,用CGLib合適,反之,使用JDK方式要更為合適一些。同時(shí),由于CGLib由于是采用動(dòng)態(tài)創(chuàng)建子類的方法,對(duì)于final方法,無法進(jìn)行代理。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • [TOC] 自定義注解 開發(fā)步驟 1.創(chuàng)建一個(gè)@interface2.String value();抽象方法用以接...
    呦後閱讀 191評(píng)論 0 0
  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和...
    九尾喵的薛定諤閱讀 3,417評(píng)論 0 2
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,820評(píng)論 11 349
  • 今晚月色好美 在淡淡的月光里 從前的樣子 今晚月色好美 在洗衣池邊 濺落的水花 今晚月色好美 在我們彼此回眸的那一...
    味兒銘閱讀 272評(píng)論 0 4
  • 1.書中自有黃金屋 關(guān)于收納 星星之火 萬馬奔騰 草原2.天空之城 白云和黑土 我想靜靜 項(xiàng)鏈 記事本 3.童話 ...
    杜觀音閱讀 187評(píng)論 0 0

友情鏈接更多精彩內(nèi)容