反射-動態代理的概述和實現
而程式執行過程中產生物件其實就是剛才反射講解的內容,所以,動態代理其實就是通過反射來生成一個代理。
在Java中java.lang.reflect包下提供了一個Proxy類和一個InvocationHandler介面,通過使用這個類和介面
就可以生成動態代理物件。JDK提供的代理只能針對介面做代理。我們有更強大的代理cglib,和後面要學的框架有關。
Proxy類中的方法建立動態代理類物件
publicstatic Object newProxyInstance(ClassLoaderloader,Class<?>[]interfaces,InvocationHandlerh)
最終會呼叫InvocationHandler的方法
InvocationHandler
Object invoke(Object proxy,Methodmethod,Object[] args)
------------------------------------------------------------------------------------------------------------------------------------
Proxy類中建立動態代理物件的方法的三個引數;
ClassLoader物件,定義了由哪個ClassLoader物件來對生成的代理物件進行載入
Interface物件的陣列,表示的是我將要給我需要代理的物件提供一組什麼介面,如果我提供了一組介面給它,那麼這個代理物件就
宣稱實現了該介面(多型),這樣我就能呼叫這組介面中的方法了
InvocationHandler物件,表示的是當我這個動態代理物件在呼叫方法的時候,會關聯到哪一個InvocationHandler物件上
------------------------------------------------------------------------------------------------------------------------------------
每一個動態代理類都必須要實現InvocationHandler這個介面,並且每個代理類的例項都關聯到了一個handler,當我們通過代理物件
呼叫一個方法的時候,這個方法的呼叫就會被轉發為由InvocationHandler這個介面的invoke 方法來進行呼叫。
InvocationHandler介面中invoke方法的三個引數:
proxy:代表動態代理物件
method:代表正在執行的方法
args:代表呼叫目標方法時傳入的實參
------------------------------------------------------------------------------------------------------------------------------------
Proxy.newProxyInstance
建立的代理物件是在jvm執行時動態生成的一個物件,它並不是我們的InvocationHandler型別,也不是我們定義的那組介面的型別,
而是在執行是動態生成的一個物件,並且命名方式都是這樣的形式,以$開頭,proxy為中,最後一個數字表示物件的標號。
System.out.println(u.getClass().getName());
------------------------------------------------------------------------------------------------------------------------------------
package cn.itcast_06;
/*
* 使用者操作介面
*/
public interface UserDao {
public abstract void add();
public abstract void delete();
public abstract void update();
public abstract void find();
}
package cn.itcast_06;
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("新增功能");
}
@Override
public void delete() {
System.out.println("刪除功能");
}
@Override
public void update() {
System.out.println("修改功能");
}
@Override
public void find() {
System.out.println("查詢功能");
}
}
package cn.itcast_06;
public interface StudentDao {
public abstract void login();
public abstract void regist();
}
package cn.itcast_06;
public class StudentDaoImpl implements StudentDao {
@Override
public void login() {
System.out.println("登入功能");
}
@Override
public void regist() {
System.out.println("註冊功能");
}
}
package cn.itcast_06;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target; // 目標物件
public MyInvocationHandler(Object target) {
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("日誌記錄");
return result; // 返回的是代理物件
}
}
package cn.itcast_06;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) {
UserDao ud = new UserDaoImpl();
ud.add();
ud.delete();
ud.update();
ud.find();
System.out.println("-----------");
// 我們要建立一個動態代理物件
// Proxy類中有一個方法可以建立動態代理物件
// public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
// 我準備對ud物件做一個代理物件,想對誰做代理,就把誰傳過來
MyInvocationHandler handler = new MyInvocationHandler(ud);
UserDao proxy = (UserDao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), handler);
proxy.add();
proxy.delete();
proxy.update();
proxy.find();
System.out.println("-----------");
StudentDao sd = new StudentDaoImpl();
MyInvocationHandler handler2 = new MyInvocationHandler(sd);
StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler2);
proxy2.login();
proxy2.regist();
/*
許可權校驗
登入功能
日誌記錄
許可權校驗
註冊功能
日誌記錄
*/
}
}
相關文章
- java 反射和動態代理Java反射
- Java動態代理和反射機制Java反射
- 深入理解 Java 反射和動態代理Java反射
- 深入淺出MyBatis:反射和動態代理MyBatis反射
- PHP 反射之動態代理PHP反射
- SAP ABAP和Java的動態代理實現Java
- JDK 和 CGLib 實現動態代理和區別JDKCGLib
- Java代理設計模式(Proxy)的四種具體實現:靜態代理和動態代理Java設計模式
- Java動態代理 jdk和cglib的實現比較JavaJDKCGLib
- Java提高班(六)反射和動態代理(JDK Proxy和Cglib)Java反射JDKCGLib
- 死磕java底層(三)—反射、動態代理和註解Java反射
- 靜態代理和動態代理
- Java代理(jdk靜態代理、動態代理和cglib動態代理)JavaJDKCGLib
- JavaScript代理模式,怎麼實現物件的動態代理?JavaScript模式物件
- Java中的靜態代理和動態代理Java
- 使用Netty和動態代理實現一個簡單的RPCNettyRPC
- CGLib動態代理原理及實現CGLib
- RPC核心實現原理-動態代理RPC
- 細說JDK動態代理的實現原理JDK
- java反射之動態代理學習筆記Java反射筆記
- MyBatis進階--介面代理方式實現Dao 和動態SQLMyBatisSQL
- 你必須會的 JDK 動態代理和 CGLIB 動態代理JDKCGLib
- 純手寫實現JDK動態代理JDK
- JDK動態代理和CGLib代理JDKCGLib
- JDK動態代理和 CGLIB 代理JDKCGLib
- 【乾貨】JDK動態代理的實現原理以及如何手寫一個JDK動態代理JDK
- [動態代理三部曲:下] - 從動態代理,看Retrofit的原始碼實現原始碼
- guava反射:Reflection.newProxy方法簡化動態代理Guava反射
- spring aop原理 JDK動態代理和CGLIB動態代理SpringJDKCGLib
- cglib動態代理和jdk動態代理的區別與應用CGLibJDK
- 反射的妙用:C#通過反射動態生成型別繼承介面並實現反射C#型別繼承
- 淺析Spring中AOP的實現原理——動態代理Spring
- 反射,註解,動態代理,依賴注入控制反轉反射依賴注入
- Spring的JDK動態代理如何實現的(原始碼解析)SpringJDK原始碼
- 靜態代理和動態代理(jdk/cglib)詳解JDKCGLib
- Java基礎系列-靜態代理和動態代理Java
- Java 靜態代理和動態代理的使用及原理解析Java
- 使用PHP實現動態代理IP的示例程式碼PHP
- 動態代理的實際應用