Java 动态代理实践AOP
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
大家都知道Spring中AOP是通過Java動(dòng)態(tài)代理實(shí)現(xiàn)的,今天就來簡(jiǎn)單學(xué)習(xí)下demo。
Java動(dòng)態(tài)代理主要有兩個(gè)核心類,InvocationHandler和Proxy。
/*** {@code InvocationHandler} is the interface implemented by* the <i>invocation handler</i> of a proxy instance.** <p>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 {@code invoke}* method of its invocation handler.** @author Peter Jones* @see Proxy* @since 1.3*/ public interface InvocationHandler所有的Handler類要實(shí)現(xiàn)InvocationHandler接口,并關(guān)聯(lián)到Proxy實(shí)例上,最后會(huì)分發(fā)到InvocationHandler的invoke方法上。
/*** {@code 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.** <p>To create a proxy for some interface {@code Foo}:* <pre>* InvocationHandler handler = new MyInvocationHandler(...);* Class proxyClass = Proxy.getProxyClass(* Foo.class.getClassLoader(), new Class[] { Foo.class });* Foo f = (Foo) proxyClass.* getConstructor(new Class[] { InvocationHandler.class }).* newInstance(new Object[] { handler });* </pre>* or more simply:* <pre>* Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),* new Class[] { Foo.class },* handler);* </pre>******************************/ public class Proxy implements java.io.Serializable通過該類的靜態(tài)方法創(chuàng)建要?jiǎng)討B(tài)代理的類。
下面看下demo
1. 先創(chuàng)建一個(gè)接口
public interface TargetInterface {int targetMethod(int num); }2. 實(shí)例化該接口
public class TargetClass implements TargetInterface {@Overridepublic int targetMethod(int number) {System.out.println("調(diào)用目標(biāo)類的方法targetMethod..."); return number; } }3. 創(chuàng)建代理處理類,InvocationHandler子類
public class ProxyHandler implements InvocationHandler {Object concreteClass;public ProxyHandler(Object concreteClass) {this.concreteClass = concreteClass;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("proxy:"+proxy.getClass().getName()); System.out.println("method:"+method.getName()); System.out.println("args:"+args[0].getClass().getName()); System.out.println("Before invoke method..."); Object object = method.invoke(concreteClass, args);System.out.println("After invoke method..."); return object; } } proxy: 指代我們所代理的那個(gè)真實(shí)對(duì)象 method: 指代的是我們所要調(diào)用真實(shí)對(duì)象的某個(gè)方法的Method對(duì)象 args: 指代的是調(diào)用真實(shí)對(duì)象某個(gè)方法時(shí)接受的參數(shù) public class Example {public static void main(String[] args) {TargetClass cc = new TargetClass();InvocationHandler ih = new ProxyHandler(cc);TargetInterface tf = (TargetInterface) Proxy.newProxyInstance(cc.getClass().getClassLoader(), cc.getClass().getInterfaces(), ih);int i = tf.targetMethod(5);} } public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentExceptionloader: 一個(gè)ClassLoader對(duì)象,定義了由哪個(gè)ClassLoader對(duì)象來對(duì)生成的代理對(duì)象進(jìn)行加載 interfaces: 一個(gè)Interface對(duì)象的數(shù)組,表示的是我將要給我需要代理的對(duì)象提供一組什么接口,如果我提供了一組接口給它,那么這個(gè)代理對(duì)象就宣稱實(shí)現(xiàn)了該接口(多態(tài)),這樣我就能調(diào)用這組接口中的方法了 h: 一個(gè)InvocationHandler對(duì)象,表示的是當(dāng)我這個(gè)動(dòng)態(tài)代理對(duì)象在調(diào)用方法的時(shí)候,會(huì)關(guān)聯(lián)到哪一個(gè)InvocationHandler對(duì)象上注意:通過?Proxy.newProxyInstance 創(chuàng)建的代理對(duì)象是在jvm運(yùn)行時(shí)動(dòng)態(tài)生成的一個(gè)對(duì)象,它并不是我們的InvocationHandler類型,也不是我們定義的那組接口的類型,而是在運(yùn)行是動(dòng)態(tài)生成的一個(gè)對(duì)象,并且命名方式都是這樣的形式,以$開頭,proxy為中,最后一個(gè)數(shù)字表示對(duì)象的標(biāo)號(hào)。
動(dòng)態(tài)代理有個(gè)缺陷,就是創(chuàng)建時(shí)需要參數(shù)interfaces,即被代理的類,需要實(shí)現(xiàn)該接口。
轉(zhuǎn)載于:https://my.oschina.net/android520/blog/700945
總結(jié)
以上是生活随笔為你收集整理的Java 动态代理实践AOP的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android中WebView加载本地H
- 下一篇: Java异常处理终结篇——如何进行Jav