大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java學習 Java動態(tài)代理原理

Java動態(tài)代理原理

更新時間:2022-05-06 10:25:00 來源:動力節(jié)點 瀏覽1368次

動力節(jié)點小編來告訴大家Java動態(tài)代理原理是什么。Java動態(tài)代理機制的出現(xiàn),給Java開發(fā)者帶來了不必手工編寫代理類,只需指定一組接口和委托類對象,就可以動態(tài)獲取代理類。代理類負責將所有的方法調(diào)用分配給委托對象進行反射執(zhí)行,在分派執(zhí)行的過程中,開發(fā)者還可以根據(jù)需要調(diào)整委托類對象及其功能,這是一個非常靈活靈活的代理框架。現(xiàn)在讓我們開始學習動態(tài)代理。

動態(tài)代理簡述在java動態(tài)代理機制中,有兩個重要的類或接口,一個是InvocationHandler(Interface)、另一個是Proxy(Class)。

InvocationHandler(interface)說明:

InvocationHandler is the interface implemented by the invocation handler of a proxy instance.
Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

每個動態(tài)代理類都必須實現(xiàn) InvocationHandler 這個接口,并且代理類的每個實例都關(guān)聯(lián)一個處理程序,當我們通過代理對象調(diào)用一種方式時,對該方法的調(diào)用會轉(zhuǎn)發(fā)到 InvocationHandler 這個接口的 invoke 方法來進行調(diào)用. 我們來看看 InvocationHandler 做這個接口的唯一方法 invoke 方法:

Object invoke(Object proxy, Method method, Object[] args) throws Throwable

該方法接受三個參數(shù)并返回一個 Object 類型,它們的含義如下:

proxy: 指我們所代表的真實對象 method: 指我們要調(diào)用真實對象的方法 Method object args: 指在真實對象上調(diào)用方法時接受的參數(shù) Back to Object真實對象方法的返回類型,以上內(nèi)容將在下面的例子中進一步理解。

the value to return from the method invocation on the proxy instance.

Proxy(Class)說明:

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.

Proxy 此類用于動態(tài)創(chuàng)建代理對象。我們經(jīng)常使用 newProxyInstance 這個方法:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

參數(shù)理解:

// One ClassLoader object , Defined by which ClassLoader Object to load the generated proxy object 
loader - the class loader to define the proxy class 
// One Interface An array of objects , What is the set of interfaces that I'm going to provide to the object that I need to proxy 
interfaces - the list of interfaces for the proxy class to implement 
// One InvocationHandler object , Represents when my dynamic proxy object is calling a method , Which one does it relate to InvocationHandler On the object 
h - the invocation handler to dispatch method invocations to

返回結(jié)果的理解:代理對象的一個??實例

a proxy instance with the specified invocation handler of a proxy class that is defined by the specified class loader and that implements the specified interfaces

普通Java代理我們創(chuàng)建一個Java項目用于測試和理解動態(tài)代理,項目結(jié)構(gòu)如下:

1.我們定義一個接口Interface,添加兩個方法。

package com.huhx.proxy;
public interface Interface {
void getMyName();
String getNameById(String id);
}

2.定義一個實現(xiàn)上述接口的真實類,RealObject:

package com.huhx.proxy;
public class RealObject implements Interface {
@Override
public void getMyName() {
System.out.println("my name is huhx");
}
@Override
public String getNameById(String id) {
System.out.println("argument id: " + id);
return "huhx";
}./* Welcome to join java communication Q Your appearance :909038429 Blow water and chat together
}

3.... 和 、 定義一個代理對象,它也實現(xiàn)了上面的接口接口:

package com.huhx.proxy;
public class SimpleProxy implements Interface {
private Interface proxied;
public SimpleProxy(Interface proxied) {
this.proxied = proxied;
}
@Override
public void getMyName() {
System.out.println("proxy getmyname");
proxied.getMyName();
}
@Override
public String getNameById(String id) {
System.out.println("proxy getnamebyid");
return proxied.getNameById(id);
}
}

4.SimpleMain在Main方法中,測試上述結(jié)果:

package com.huhx.proxy;
public class SimpleMain {
private static void consume(Interface iface) {
iface.getMyName();
String name = iface.getNameById("1");
System.out.println("name: " + name);
}
public static void main(String[] args) {
consume(new RealObject());
System.out.println("========================================================");
consume(new SimpleProxy(new RealObject()));
}
}

5.... 和 、 運行結(jié)果如下:

my name is huhx
argument id: 1
name: huhx
========================================================
proxy getmyname
my name is huhx
proxy getnamebyid
argument id: 1
name: huhx

Java動態(tài)代理完成了上面簡單的Java代理,現(xiàn)在我們開始學習Java動態(tài)代理,它比代理的思想更進了一步,因為它可以動態(tài)創(chuàng)建代理并動態(tài)處理對代理方法的調(diào)用。在動態(tài)代理上進行的所有調(diào)用都被重定向到單個調(diào)用處理程序,它的工作是揭示調(diào)用的類型并確定相應的對策。下面我們通過案例加深對Java動態(tài)代理的理解:

1.創(chuàng)建一個繼承 InvocationHandler 的處理器:DynamicProxyHandler

package com.huhx.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;
public class DynamicProxyHandler implements InvocationHandler {
private Object proxied;
public DynamicProxyHandler(Object proxied) {
System.out.println("dynamic proxy handler constuctor: " + proxied.getClass());
this.proxied = proxied;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("dynamic proxy name: " + proxy.getClass());
System.out.println("method: " + method.getName());
System.out.println("args: " + Arrays.toString(args));
Object invokeObject = method.invoke(proxied, args);
if (invokeObject != null) {
System.out.println("invoke object: " + invokeObject.getClass());
} else {
System.out.println("invoke object is null");
}
return invokeObject;
}
}

2.我們寫一個測試Main方法,DynamicProxyMain:

package com.huhx.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import com.huhx.proxy.Interface;
import com.huhx.proxy.RealObject;
public class DynamicProxyMain {
public static void consumer(Interface iface) {
iface.getMyName();
String name = iface.getNameById("1");
System.out.println("name: " + name);
}
public static void main(String[] args) throws Exception, SecurityException, Throwable {
RealObject realObject = new RealObject();
consumer(realObject);
System.out.println("==============================");
// A dynamic proxy 
ClassLoader classLoader = Interface.class.getClassLoader();
Class<?>[] interfaces = new Class[] { Interface.class };
InvocationHandler handler = new DynamicProxyHandler(realObject);
Interface proxy = (Interface) Proxy.newProxyInstance(classLoader, interfaces, handler);
System.out.println("in dynamicproxyMain proxy: " + proxy.getClass());
consumer(proxy);
}./* Welcome to join java communication Q Your appearance :909038429 Blow water and chat together
}

3. ... 和 、 運行結(jié)果如下:

my name is huhx
argument id: 1
name: huhx
==============================
dynamic proxy handler constuctor: class com.huhx.proxy.RealObject
in dynamicproxyMain proxy: class com.sun.proxy.$Proxy0
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getMyName
args: null
my name is huhx
invoke object is null
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getNameById
args: [1]
argument id: 1
invoke object: class java.lang.String
name: huhx

從以上輸出,我們可以得出以下結(jié)論:

與代理對象InvocationHandler相關(guān)聯(lián),只有當代理對象調(diào)用一個方法時,才進行invoke方法invoke 的三個參數(shù)的理解:對象代理是代理的對象,方法方法是真實對象調(diào)用的方法class , Object[] args 是真實對象中調(diào)用方法的參數(shù)

Java動態(tài)代理的原理

1.動態(tài)代理的關(guān)鍵代碼是Proxy.newProxyInstance(classLoader, interfaces, handler),我們跟進源碼看看:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
// handler Can't be empty 
if (h == null) {
throw new NullPointerException();
}
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
*/
// adopt loader And interface , Get a proxy Class object 
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
*/
try {
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
// create proxy instance with doPrivilege as the proxy class may
// implement non-public interfaces that requires a special permission
return AccessController.doPrivileged(new PrivilegedAction<Object>() {
public Object run() {
return newInstance(cons, ih);
}
});
} else {
// Create an instance of the proxy object 
return newInstance(cons, ih);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString());
}
}

2.我們來看newInstance方法的源碼:

private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
try {
return cons.newInstance(new Object[] {h} );
} catch (IllegalAccessException | InstantiationException e) {
throw new InternalError(e.toString());
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString());
}
}
}

3....和、 當我們通過代理對象調(diào)用一種方式時,對該方法的調(diào)用轉(zhuǎn)發(fā) InvocationHandler 這個接口的 invoke 方法進行調(diào)用。體現(xiàn)這句話的代碼,在源碼中沒有找到,所以在測試類的main方法中添加如下代碼:

if (proxy instanceof Proxy) {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
invocationHandler.invoke(proxy, realObject.getClass().getMethod("getMyName"), null);
System.out.println("--------------------------------------");
}

這段代碼的輸出如下,而且,在上面,調(diào)用代理對象getMyName的方法輸出是一樣的,不知道!jvm 是否按此方式判斷到底:

dynamic proxy handler constuctor: class com.huhx.proxy.RealObject
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getMyName
args: null
my name is huhx
invoke object is null

通過上述介紹,相信大家對Java動態(tài)代理原理已經(jīng)有所了解,大家如果想了解更多相關(guān)知識,不妨來關(guān)注一下動力節(jié)點的Java在線學習,里面還有更豐富的知識等著大家去學習,希望對大家能夠有所幫助哦。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 欧美一区二区三区综合色视频 | 欧美影院一区二区 | 免费特黄一级欧美大片在线看 | 免费观看日本高清a毛片 | 精品国产亚洲一区二区三区 | 九九视频免费看 | 青青久在线视频免费视频 | 久久久999久久久精品 | 精品亚洲视频在线观看 | 欧美久色 | 久久亚洲这里只有精品18 | 国产成人香蕉在线视频网站 | 亚洲一区二区免费视频 | 久久久久久国产精品视频 | 久久一区二区精品 | 2019年国产高清情侣视频 | 91国语精品自产拍在线观看一 | 欧美激情亚洲 | 一级毛片免费毛片一级毛片免费 | 天天综合射 | 亚洲国产精品成人久久 | 久久国产精品亚洲一区二区 | 97久久精品人人澡人人爽 | 亚洲精品中文字幕区 | 99久久99视频 | 色中色综合网 | 国产午夜久久精品 | 国产精品国色综合久久 | 久久成人国产精品免费 | 亚洲美女视频免费 | 这里只有精品视频在线 | 日本不卡在线视频 | 久久最稳定资源站在线 | 亚洲国产精品网 | 一区二区在线不卡 | 国产精久久一区二区三区 | 久久精品亚洲综合一品 | 99国产福利视频在线观看 | 天天躁日日躁狠狠躁综合 | 在哪里可以看毛片 | 一级黄色毛片子 |