最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring靜態(tài)代理和動態(tài)代理代碼詳解

 更新時間:2017年11月27日 10:37:54   作者:zhouyeqin  
這篇文章主要介紹了Spring靜態(tài)代理和動態(tài)代理代碼詳解,具有一定參考價值,需要的朋友可以了解下。

本節(jié)要點:

Java靜態(tài)代理
Jdk動態(tài)代理

1 面向?qū)ο笤O(shè)計思想遇到的問題

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

現(xiàn)在假設(shè)系統(tǒng)中有三段完全相似的代碼,這些代碼通常會采用“復(fù)制”、“粘貼”方式來完成,通過這種方式開發(fā)出來的軟件如圖所示:

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

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

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

//log4j的使用見文章“l(fā)og4j介紹”
import org.apache.log4j.Logger;
public class Person {
	private Logger logger = Logger.getLogger(Person.class);
	public void sleep(){
		logger.info(“開始執(zhí)行時間:“ + new Date());
		System.out.println("睡覺中");
		logger.info(“執(zhí)行結(jié)束時間:” + new Date());
	}
	public void eating(){
		logger.info("開始執(zhí)行時間:“ + new Date()");
		System.out.println("正在吃飯中");
		logger.info("“執(zhí)行結(jié)束時間:” + new Date()");
	}
}

提問:弊端在哪里?

l混淆了業(yè)務(wù)方法本身的職責(zé)

l維護(hù)工作量巨大

2解決方案1

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

l目地是將業(yè)務(wù)代碼與日志代碼完全分離,實現(xiàn)松散耦合.

l代理對象與被代理對象必須實現(xiàn)同一接口,在代理對象中實現(xiàn)與日志記錄的相關(guān)服務(wù),并在需要的時候呼叫被代理對象,而被代理對象只保留業(yè)務(wù)代碼.

靜態(tài)代理的實現(xiàn)

1)定義接口:

public interface IPerson {
	public abstract void sleep();
	public abstract void eating();
}

2) 被代理類

public class Person implements IPerson {
	public void sleep(){
		System.out.println("睡覺中");
	}
	public void eating(){
		System.out.println("正在吃飯中");
	}
}

3) 代理類

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("開始執(zhí)行時間:“ + new Date()");
		person.eating();
		logger.info("“執(zhí)行結(jié)束時間:” + new Date()");
	}
	public void sleep() {
		logger.info("開始執(zhí)行時間:“ + new Date()");
		person.sleep();
		logger.info("“執(zhí)行結(jié)束時間:” + new Date()");
	}
}

4) 測試類

package com.aptech.aop2;
public class PersonTest {
	public static void main(String[] args) {
		IPerson proxy = new PersonProxy(new Person());
		proxy.eating();
		proxy.sleep();
	}
}

靜態(tài)代理的弊端:

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

3 解決方案2-動態(tài)代理

InvocationHandler:每一個動態(tài)代理類都必須實現(xiàn)InvocationHandler這個接口,并且每個代理類的實例都關(guān)聯(lián)到了一個handler,當(dāng)我們通過代理對象調(diào)用一個方法的時候,這個方法的調(diào)用就會被轉(zhuǎn)發(fā)為由InvocationHandler這個接口的invoke方法來進(jìn)行調(diào)用。

在JDK1.3之后加入了可協(xié)助開發(fā)的動態(tài)代理功能.不必為特定對象與方法編寫特定的代理對象,使用動態(tài)代理,可以使得一個處理者(Handler)服務(wù)于各個對象.
一個處理者的類設(shè)計必須實現(xiàn)java.lang.reflect.InvocationHandler接口.
通過InvocationHandler接口實現(xiàn)的動態(tài)代理只能代理接口的實現(xiàn)類.

動態(tài)代理實現(xiàn)

1) 處理者(Handler)

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("執(zhí)行開始時間:" + new Date());
		Object result = method.invoke(target, args);
		logger.info("執(zhí)行結(jié)束時間:" + new Date());
		return result;
		//返回method執(zhí)行結(jié)果
	}
}

2) 生產(chǎn)代理對象的工廠

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) 測試類

public class PersonTest {
	public static void main(String[] args) {
		IPerson person = (IPerson) DynaProxyFactory.getProxy(new Person());
		//返回代理類,代理類是JVM在內(nèi)存中動態(tài)創(chuàng)建的,該類實現(xiàn)傳入的接口數(shù)組的全部接口(的全部方法).
		person.eating();
		person.sleep();
	}
}

總結(jié)

以上就是本文關(guān)于Spring靜態(tài)代理和動態(tài)代理代碼詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

Spring常用配置及解析類說明

SpringMVC攔截器實現(xiàn)單點登錄

Java編程實現(xiàn)springMVC簡單登錄實例

如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

相關(guān)文章

  • Shiro+Redis實現(xiàn)登錄次數(shù)凍結(jié)的示例

    Shiro+Redis實現(xiàn)登錄次數(shù)凍結(jié)的示例

    這篇文章主要介紹了Shiro+Redis實現(xiàn)登錄次數(shù)凍結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • Java實例化一個抽象類對象的方法教程

    Java實例化一個抽象類對象的方法教程

    大家都知道抽象類無法實例化,就無法創(chuàng)建對象。所以下面這篇文章主要給大家介紹了關(guān)于Java實例化一個抽象類對象的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-12-12
  • 一文梳理Java超大型文件讀取的18種方法和性能

    一文梳理Java超大型文件讀取的18種方法和性能

    這篇文章主要為大家詳細(xì)介紹了Java中超大型文件讀取的18種方法和性能對比,文中的示例代碼簡潔易懂,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • 關(guān)于EntityWrapper的in用法

    關(guān)于EntityWrapper的in用法

    這篇文章主要介紹了關(guān)于EntityWrapper的in用法詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • springboot將lib和jar分離的操作方法

    springboot將lib和jar分離的操作方法

    本文介紹了如何通過優(yōu)化pom.xml配置來減小Spring Boot項目的jar包大小,主要通過使用spring-boot-maven-plugin和maven-dependency-plugin插件,將依賴庫打包到j(luò)ar中,并通過指定外部lib路徑的方式運行jar,從而減小jar包體積,感興趣的朋友一起看看吧
    2025-02-02
  • 項目打包成jar后包無法讀取src/main/resources下文件的解決

    項目打包成jar后包無法讀取src/main/resources下文件的解決

    本文主要介紹了項目打包成jar后包無法讀取src/main/resources下文件的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 聊聊Spring——AOP詳解(AOP概覽)

    聊聊Spring——AOP詳解(AOP概覽)

    這篇文章主要介紹了Spring——AOP詳解(AOP概覽),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • java8 集合 多字段 分組 統(tǒng)計個數(shù)代碼

    java8 集合 多字段 分組 統(tǒng)計個數(shù)代碼

    這篇文章主要介紹了java8 集合 多字段 分組 統(tǒng)計個數(shù)代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Java鍵盤錄入Scanner類的使用方法詳析

    Java鍵盤錄入Scanner類的使用方法詳析

    在Java編程中,引用數(shù)據(jù)類型是用來存儲對象的引用(地址),而Scanner類是引用數(shù)據(jù)類型的一種,用于讀取輸入數(shù)據(jù),文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-09-09
  • 調(diào)用Mybatis?plus中的saveBatch方法報找不到表的問題

    調(diào)用Mybatis?plus中的saveBatch方法報找不到表的問題

    在用Mybatis plus開發(fā)的項目中,用自帶的API批量保存的方法saveBatch操作時,發(fā)現(xiàn)報沒有找到表的錯誤,本文就來詳細(xì)的介紹一下解決方法,感興趣的可以了解一下
    2024-03-03

最新評論

保山市| 尼木县| 隆林| 新密市| 乳山市| 江孜县| 龙南县| 苗栗县| 宜章县| 霍林郭勒市| 大同市| 科技| 周至县| 万源市| 尉氏县| 桂东县| 咸宁市| 彝良县| 丹江口市| 米泉市| 搜索| 荔波县| 广元市| 抚州市| 龙江县| 隆子县| 巴楚县| 尤溪县| 屏东县| 穆棱市| 婺源县| 曲松县| 麻江县| 泽州县| 富阳市| 义马市| 定日县| 确山县| 武邑县| 黔西县| 康马县|