欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 動態(tài)代理的多種實現方式

 更新時間:2021年06月07日 09:25:13   作者:卡修斯  
動態(tài)代理實際上是JVM在運行期動態(tài)創(chuàng)建class字節(jié)碼并加載的過程。本文講述了Java 動態(tài)代理的多種實現方式,感興趣的朋友可以選擇適合自己的方式

一、動態(tài)代理簡介

優(yōu)勢:在不修改源碼的情況下,對目標方法進行相應的增強。

作用:完成程序功能之間的松耦合。

二、動態(tài)代理的多種實現

  • JDK代理:基于接口的動態(tài)代理技術(缺點,目標對象必須有接口,如果沒有接口,則無法完成動態(tài)代理的實現)
  • cglib代理:基于父類的動態(tài)代理技術

兩者的區(qū)別如圖所示:

1. 基于JDK的實現

目標接口類:

public interface TargetInterface {
	public void save();
	
	public void print(String str);
}

目標類:

public class Target implements TargetInterface{
	
	public void save() {
		System.out.println("save running...");
	}
	
	public void print(String str) {
		System.out.println(str);
	}

}

增強類:

public class Advice {
	public void before() {
		System.out.println("前置增強");
	}

	public void after() {
		System.out.println("后置增強");
	}
}

測試類:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {

	public static void main(String[] args) {
		
		//目標對象
		final Target target = new Target();
		
		//增強對象
		final Advice advice = new Advice();
		
		TargetInterface proxyInstance = (TargetInterface)Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 					//目標對象類加載器
				target.getClass().getInterfaces(), 						//目標對象相同的接口字節(jié)碼對象數組
				new InvocationHandler() {
					//調用代理對象的任何方法,實質執(zhí)行的都是invoke方法
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{
						advice.before();								//前置增強
						Object invoke = method.invoke(target, args);	//執(zhí)行目標方法
						advice.after();									//后置增強
						System.out.println();
						return invoke;
					}
				});
		
		//代理對象的方法測試
		proxyInstance.save();
		
		proxyInstance.print("JDK動態(tài)代理");
	}

}

運行截圖:

2. 基于cglib的實現

需要導入Jar包,如果是maven項目,則在pom.xml文件加入如下配置:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.2.4.RELEASE</version>
</dependency>

目標類:

public class Target {
	public void save() {
		System.out.println("save running...");
	}
	
	public void print(String str) {
		System.out.println(str);
	}
}

增強類:

public class Advice {
	
	public void before() {
		System.out.println("前置增強");
	}

	public void after() {
		System.out.println("后置增強");
	}

}

測試類:

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class ProxyTest {

	public static void main(String[] args) {
		final Target target = new Target();
		final Advice advice = new Advice();
		
		//返回值就是動態(tài)生成的代理對象,基于cglib
		//創(chuàng)建增強器
		Enhancer enhancer = new Enhancer();
		
		//設置父類(目標)
		enhancer.setSuperclass(Target.class);
		
		//設置回調
		enhancer.setCallback(new MethodInterceptor() {
			public Object intercept(Object o, Method method, Object[] obj, MethodProxy methodProxy) throws Throwable{
				advice.before();
				Object invoke = method.invoke(target, obj);
				advice.after();
				System.out.println();
				return invoke;
			}
		});
		
		//創(chuàng)建代理對象
		Target proxy = (Target)enhancer.create();
		
		//測試代理方法
		proxy.save();
		proxy.print("基于cglib實現動態(tài)規(guī)劃");
		
	}

}

運行截圖:

三、為什么要有基于cglib的實現

使用JDK動態(tài)代理實現時,最大限制是被增強對象必須實現接口,并且增強的方法只能是接口中聲明的方法。但在實際的項目中,可能總是存在對不實現業(yè)務接口的對象進行增強的需求,這時JDK動態(tài)代理將無能為力。

四、兩種方式的適用場景

JDK動態(tài)代理

優(yōu)點

  • 不依賴第三方jar包, 使用方便
  • 隨著JDK的升級,JDK動態(tài)代理的性能在穩(wěn)步提升

缺點

  • 只能代理實現了接口的類
  • 執(zhí)行速度較慢

適用場景

  • 如果你的程序需要頻繁、反復地創(chuàng)建代理對象,則JDK動態(tài)代理在性能上更占優(yōu)。

cglib

優(yōu)點

由于是動態(tài)生成字節(jié)碼實現代理,因此代理對象的執(zhí)行速度較快, 約為JDK動態(tài)代理的1.5 ~ 2倍
可以代理沒有實現接口的對象

缺點

  • 不能代理final類
  • 動態(tài)生成字節(jié)碼雖然執(zhí)行較快,但是生成速度很慢,根據網上一些人的測試結果,cglib創(chuàng)建代理對象的速度要比JDK慢10 ~ 15倍。

適用場景

  • 不需要頻繁創(chuàng)建代理對象的應用,如Spring中默認的單例bean,只需要在容器啟動時生成一次代理對象。

以上就是Java 動態(tài)代理的多種實現方式的詳細內容,更多關于Java 動態(tài)代理的實現的資料請關注腳本之家其它相關文章!

相關文章

  • 為什么Spring和IDEA都不推薦使用 @Autowired 注解

    為什么Spring和IDEA都不推薦使用 @Autowired 注解

    本文主要介紹了為什么Spring和IDEA都不推薦使用 @Autowired 注解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-04-04
  • Java常用JVM參數實戰(zhàn)

    Java常用JVM參數實戰(zhàn)

    本文主要介紹了Java常用JVM參數實戰(zhàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05
  • java結合HADOOP集群文件上傳下載

    java結合HADOOP集群文件上傳下載

    這篇文章主要介紹了java結合HADOOP集群文件上傳下載的方法和示例,非常的實用,這里推薦給大家,希望大家能夠喜歡。
    2015-03-03
  • Springboot單體架構http請求轉換https請求來支持微信小程序調用接口

    Springboot單體架構http請求轉換https請求來支持微信小程序調用接口

    這篇文章主要介紹了Springboot單體架構http請求轉換https請求來支持微信小程序調用接口,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • JAVA實現生成順序ID,不浪費ID

    JAVA實現生成順序ID,不浪費ID

    這篇文章主要介紹了JAVA實現生成順序ID,不浪費ID問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • SpringBoot靜態(tài)視頻實時播放的實現代碼

    SpringBoot靜態(tài)視頻實時播放的實現代碼

    這篇文章主要介紹了SpringBoot靜態(tài)視頻實時播放的實現代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-01-01
  • Java多線程的用法詳解

    Java多線程的用法詳解

    本篇文章介紹了,在Java中多線程的用法詳解。需要的朋友參考下
    2013-04-04
  • Struts 2 數據校驗功能及校驗問題的解決方案

    Struts 2 數據校驗功能及校驗問題的解決方案

    這篇文章主要介紹了Struts 2 數據校驗功能及校驗問題的解決方案的相關資料,需要的朋友可以參考下
    2016-09-09
  • 簡單了解Spring Cloud Alibaba相關知識

    簡單了解Spring Cloud Alibaba相關知識

    這篇文章主要介紹了簡單了解Spring Cloud Alibaba相關知識,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-10-10
  • 全面了解OAuth?2.0四種授權方式金三銀四無懼面試

    全面了解OAuth?2.0四種授權方式金三銀四無懼面試

    這篇文章主要介紹了全面了解OAuth?2.0四種授權方式金三銀四無懼面試,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-02-02

最新評論