動態代理模式
今天的主要內容:
全是干貨,整理不易!請各位走過路過點點贊!
例子中使用的代碼大家可以隨意自取,適合學習了java反射機制的同學觀看 ,如果沒有學習過,我的博客主頁中有java的反射機制的我自己整理的學習日記可供觀看嗷
今天我們要淺層理解AOP,對我一個第一次接觸這個東西的萌新有點慌
總結的東西可能有不對的地方希望路過的大神能夠指出!感激不盡!
理解面向切面編程AOP:
AOP全稱:Aspect Oriented Programming
將散落在業務邏輯各個角落的、具有橫切性特點的代碼在合適的切入點、合適的時機切入到目標代碼的執行程序中去,實作與業務邏輯的分離、解耦,更加便于維護、管理
反射機制->動態代理模式->AOP
java中動態代理模式的實作:
動態代理的核心類及介面:
java.lang.reflect.InvocationHandler
java.lang.reflect.Proxy
接下來我們就用一個買房子的例子來解釋什么是動態代理模式:
我們用到三個類,一個介面:
1.Owner類:找代理人的人,業主
2.Buyable介面:代理人能做的方法,也是要被橫向織入的各種方法的集合
所以這里Owner implements Buyable
3.OwnerProxyInvocationHandler類:業主代理的呼叫處理器
一般這個代理類都要實作一個介面叫InvocationHandler
通俗的將這個類是用來實作橫向織入程序的,將業主要
被代理使用但不更改原來方法的動作在這個類里待命
4.Test類:功能測驗類
這次例子的主要實作邏輯(重要!必看!):
首先我們創建一個Owner類,也就是業主類,業主類接上Buyable能力的介面,
得到Buyable介面中的方法,然后我們撰寫一個OwnerProxyInvocationHandler
類,這個類將業主需要找代理商去做的事情以自己的方式在保留業主的原來方法
的情況下做出來,然后在測驗類里面創建一個代理人,這個代理人實體一般都是
業主的能力介面的物件,好下面我們開始,
本次動態代理例子中重要的幾個方法 (重要!可以與代碼一起看):
1.Proxy.newProxyInstance(ClassLoader loader, Class<?> interfaces, InvocationHandler h)
第一個引數:類加載器,就是我們當前所在類的加類載器,例子中為Test.getClass().getClassLoader()
第二個引數:被代理目標的所有介面,例子里是o1.getClass.getInterfaces()
第三個引數:代理物件的方法要被哪個類處理就填誰,例子中為new OwnerProxyInvcationHandler(o1)
2.public Object invoke(Object proxy, Method method, Object[] args) throws Throwable他是InvocationHandler介面中需要重寫的方法,也是橫向織入的核心方法,
第一個引數:可以將代理物件回傳以進行連續呼叫,且不斷允許反射產生Proxy實體,
第二個引數:我們需要被代理的哪個物件的方法那個方法被Method封裝成了一個物件
第三個引數:被代理的方法引數
廢話不多說!上代碼!(結合前邊知識點看效果更佳)
Owner類:
package LessonForDynamicProxyPattern;
//Owner類此時為被代理物件!
public class Owner implements Buyable
{
@Override
public void payCash()
{
System.out.println("---呼叫payCash()方法---");
}
@Override
public int makeMoney(int amount)
{
System.out.println("---呼叫makeMoney(int amount)方法---");
return amount*1000;
}
}
OwnerProxyInvocationHandler類:
package LessonForDynamicProxyPattern;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class OwnerProxyInvcationHandler implements InvocationHandler
{
/*
*public Object invoke(Object proxy, Method method, Object[] args) throws Throwable方法
* 第一個引數:產生了代理實體
* 第二個引數:我們需要被代理的那個方法的物件,那個方法被Method封裝成一個物件
* 第三個引數:被代理的方法的引數
*/
private Object target;//幫忙代理的代理目標
public OwnerProxyInvcationHandler(Object target)
{
super();
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
System.out.println("被代理的方法執行前,,,,,");
Object result = method.invoke(target, args);
/*
* 這里第一個引數:是被代理目標
* 這里第二個引數:是被代理方法的引數,如果沒有就這樣擺著就行了
* 這里有回傳值,回傳值是什么呢,是被我們代理的目標方法的回傳值,我們具體情況具體向下轉型
*/
System.out.println("被代理方法執行之后我標記了一下");
/*
* 28~35行就是AOP的橫切面邏輯,目標方法執行前我們要求有動作,目標方法執行后我們也要求有動作
* 但是這些前后要執行的動作沒有被硬寫到被代理的目標物件的那個方法中去,實作松耦合
*/
return result;
}
}
Buyable介面:
package LessonForDynamicProxyPattern;
public interface Buyable //核心業務介面
{
public void payCash();
public int makeMoney(int amount);
}
Test類:
package LessonForDynamicProxyPattern;
import java.lang.reflect.Proxy;
public class Test
{
public static void main(String[] args)
{
Owner o1 = new Owner();//找代理人的人
/*
*Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
* 第一個引數:類加載器,就是我們當前的類,此時為Test.class.getClassLoader()
* 第二個引數:被代理目標的所有介面,在這個例子中為o1.getClass().getInterfaces()
* 第三個引數:代理物件的方法被代理之后,例子中為new OwnerProxyInvcationHandler(o1)
*
* newProxyInstance回傳的就是我們的代理物件實體,一般要為我們的介面
*/
Buyable by1 = (Buyable)Proxy.newProxyInstance(Test.class.getClassLoader(),
o1.getClass().getInterfaces(),
new OwnerProxyInvcationHandler(o1));//新創建一個“代理人”實體
by1.payCash();//動態織入程序
System.out.println("----------------------------------");
int rent = by1.makeMoney(10);
System.out.println(rent);
}
}
部分文字來源于:
咕嘟咖啡楊海濱老師 — 《java編程語言高級特性》
在這里十分感謝老師能夠給我帶來學習的激情.
2020.10.08
可以轉載我的學習日記但請注明出處,謝謝,
畢!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/167044.html
標籤:AI
