一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Spring靜態代理和動態代理代碼詳解

Spring靜態代理和動態代理代碼詳解

2021-02-22 10:51zhouyeqin Java教程

這篇文章主要介紹了Spring靜態代理和動態代理代碼詳解,具有一定參考價值,需要的朋友可以了解下。

本節要點:

java靜態代理
jdk動態代理

1 面向對象設計思想遇到的問題

在傳統oop編程里以對象為核心,并通過對象之間的協作來形成一個完整的軟件功能,由于對象可以繼承,因此我們可以把具有相同功能或相同特征的屬性抽象到一個層次分明的類結構體系中。隨著軟件規范的不斷擴大,專業化分工越來越系列,以及oop應用實踐的不斷增多,隨之也暴露了一些oop無法很好解決的問題。

現在假設系統中有三段完全相似的代碼,這些代碼通常會采用“復制”、“粘貼”方式來完成,通過這種方式開發出來的軟件如圖所示:

Spring靜態代理和動態代理代碼詳解

可能讀者已經發現了這種做法的不足之處,如果有一天,藍色背景的代碼需要修改,那是不是要同時修改三個地方?如果不僅僅是這三個地方包含這段代碼,而是100個,甚至是1000個地方,那會是什么后果?

記錄日志在代碼中無處不在---先來看一個例子:

為了跟蹤應用程序的運行過程,很多方法都需要記錄日志信息。我們一般這樣寫:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//log4j的使用見文章“log4j介紹”
import org.apache.log4j.logger;
public class person {
    private logger logger = logger.getlogger(person.class);
    public void sleep(){
        logger.info(“開始執行時間:“ + new date());
        system.out.println("睡覺中");
        logger.info(“執行結束時間:” + new date());
    }
    public void eating(){
        logger.info("開始執行時間:“ + new date()");
        system.out.println("正在吃飯中");
        logger.info("“執行結束時間:” + new date()");
    }
}

提問:弊端在哪里?

l混淆了業務方法本身的職責

l維護工作量巨大

2解決方案1

靜態代理:
   1、需要知道核心類(被代理類)是哪一個類,并且有什么方法。 
   2、非核心的代碼需要重復寫多次,顯得代碼的結構臃腫,形成代碼冗余。
   3、非核心類(代理類)需要實現核心類(被代理類)實現的接口,也就是他們需要實現共同的接口,但是以核心類實現的接口(被代理類)為準。

l目地是將業務代碼與日志代碼完全分離,實現松散耦合.

l代理對象與被代理對象必須實現同一接口,在代理對象中實現與日志記錄的相關服務,并在需要的時候呼叫被代理對象,而被代理對象只保留業務代碼.

靜態代理的實現

1)定義接口:

?
1
2
3
4
public interface iperson {
    public abstract void sleep();
    public abstract void eating();
}

2) 被代理類

?
1
2
3
4
5
6
7
8
public class person implements iperson {
    public void sleep(){
        system.out.println("睡覺中");
    }
    public void eating(){
        system.out.println("正在吃飯中");
    }
}

3) 代理類

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.apache.log4j.logger;
public class personproxy implements iperson {
    private iperson person;
    private logger logger = logger.getlogger(personproxy.class);
    public personproxy(iperson person) {
        this.person = person;
    }
    public void eating() {
        logger.info("開始執行時間:“ + new date()");
        person.eating();
        logger.info("“執行結束時間:” + new date()");
    }
    public void sleep() {
        logger.info("開始執行時間:“ + new date()");
        person.sleep();
        logger.info("“執行結束時間:” + new date()");
    }
}

4) 測試類

?
1
2
3
4
5
6
7
8
package com.aptech.aop2;
public class persontest {
    public static void main(string[] args) {
        iperson proxy = new personproxy(new person());
        proxy.eating();
        proxy.sleep();
    }
}

靜態代理的弊端:

一個代理接口只能服務于一種類型的對象.對于稍大點的項目根本無法勝任.

3 解決方案2-動態代理

invocationhandler:每一個動態代理類都必須實現invocationhandler這個接口,并且每個代理類的實例都關聯到了一個handler,當我們通過代理對象調用一個方法的時候,這個方法的調用就會被轉發為由invocationhandler這個接口的invoke方法來進行調用。

在jdk1.3之后加入了可協助開發的動態代理功能.不必為特定對象與方法編寫特定的代理對象,使用動態代理,可以使得一個處理者(handler)服務于各個對象.
一個處理者的類設計必須實現java.lang.reflect.invocationhandler接口.
通過invocationhandler接口實現的動態代理只能代理接口的實現類.

動態代理實現

1) 處理者(handler)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class dynaproxyhandler implements invocationhandler {
    private logger logger = logger.getlogger(dynaproxyhandler.class);
    private object target;
    //被代理對象
    public void settarget(object target) {
        this.target = target;
    }
    public object invoke(object proxy, method method, object[] args)
                  throws throwable {
        logger.info("執行開始時間:" + new date());
        object result = method.invoke(target, args);
        logger.info("執行結束時間:" + new date());
        return result;
        //返回method執行結果
    }
}

2) 生產代理對象的工廠

?
1
2
3
4
5
6
7
8
9
import java.lang.reflect.proxy;
public class dynaproxyfactory {
    //obj為被代理對象
    public static object getproxy(object obj){
        dynaproxyhandler handler = new dynaproxyhandler();
        handler.settarget(obj);
        return proxy.newproxyinstance(obj.getclass().getclassloader(), obj.getclass().getinterfaces(), handler);
    }
}

3) 測試類

?
1
2
3
4
5
6
7
8
public class persontest {
    public static void main(string[] args) {
        iperson person = (iperson) dynaproxyfactory.getproxy(new person());
        //返回代理類,代理類是jvm在內存中動態創建的,該類實現傳入的接口數組的全部接口(的全部方法).
        person.eating();
        person.sleep();
    }
}

總結

以上就是本文關于spring靜態代理和動態代理代碼詳解的全部內容,希望對大家有所幫助。如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

原文鏈接:https://www.cnblogs.com/zhouyeqin/p/7208367.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本高清动作片www欧美 | 精品一区二区视频 | 国产精品久久久久久久牛牛 | 91国内精品久久久久怡红院 | 精品午夜寂寞黄网站在线 | 日本高清免费不卡在线 | 亚洲2023无矿砖码砖区 | 亚洲福利精品电影在线观看 | 免费大片| 亚洲成年网站在线观看 | 亚洲精品短视频 | 青青在线| 女人肮脏的交易中文字幕未删减版 | 337p大尺度啪啪人体午夜2020 | 国产精品国产三级在线专区 | 午夜看片a福利在线观看 | 精品福利视频一区二区三区 | 手机国产乱子伦精品视频 | 亚洲精品老司机福利在线播放 | 波多野结衣xxxx性精品 | 国产精品一区二区久久不卡 | 国内免费高清视频在线观看 | 亚洲国产精品ⅴa在线观看 亚洲国产高清一区二区三区 | 男人晚上适合偷偷看的污污 | 成人看的羞羞视频免费观看 | 无码一区国产欧美在线资源 | 日本亚洲娇小与黑人tube | 小鸟酱在线播放 | 亚洲AV无码偷拍在线观看 | 久久99re2热在线播放7 | 狠狠综合久久综合网站 | 青青草人人 | 四虎最新免费观看网址 | 国产精品欧美韩国日本久久 | 国产一区私人高清影院 | 99热这里只有精 | 日本人妖网站 | 日本三级成人中文字幕乱码 | 久久这里只有精品国产精品99 | 精品国产线拍大陆久久尤物 | 爽新片xxxxxxx |