2020久久超碰欧美精品最新亚洲欧美日韩久久精品,国产福利电影一区二区三区,亚洲欧美日韩一区在线观看,亚洲国产欧美日韩欧美特级,亚洲欧美日韩成人一区久久,欧美日韩精品一区二区三区不卡,国产欧美日韩va另类影音先锋,亚洲欧美日韩久久精品,亚洲欧美日韩国产成人精品影院,亚洲国产欧美日韩精品一区二区三区,欧美日韩国产成人高清视频,日韩久久精品国产免费观看频道,久久人人爽人人爽从片av高清,国产精品综合一区二区

首頁技術文章正文

Spring中的JDK動態代理是如何實現的?

更新時間:2021-05-25 來源:黑馬程序員 瀏覽量:

1577370495235_學IT就到黑馬程序員.gif

JDK動態代理是通過java.lang.reflect.Proxy 類來實現的,我們可以調用Proxy類的newProxyInstance()方法來創建代理對象。對于使用業務接口的類,Spring默認會使用JDK動態代理來實現AOP。

接下來,通過一個案例來演示Spring中JDK動態代理的實現過程,具體步驟如下。

(1)創建一個名為chapter03的Web項目,導入Spring框架所需JAR包到項目的lib目錄中,并發布到類路徑下。

(2)在src目錄下,創建一個com.itheima.jdk包,在該包下創建接口UserDao,并在該接口中編寫添加和刪除的方法,如文件1所示。

文件1 UserDao.java

     package com.itheima.jdk;
     public interface UserDao {
        public void addUser();
         public void deleteUser();
     }

(3)在com.itheima.jdk包中,創建UserDao接口的實現類UserDaoImpl,分別實現接口中的方法,并在每個方法中添加一條輸出語句,如文件2所示。

文件2 UserDaoImpl.java

     package com.itheima.jdk;
     // 目標類
     public class UserDaoImpl implements UserDao {
         public void addUser() {
             System.out.println("添加用戶");
         }
         public void deleteUser() {
             System.out.println("刪除用戶");
         }
     }

需要注意的是,本案例中會將實現類UserDaoImpl作為目標類,對其中的方法進行增強處理。

(4)在src目錄下,創建一個com.itheima.aspect包,并在該包下創建切面類MyAspect,在該類中定義一個模擬權限檢查的方法和一個模擬記錄日志的方法,這兩個方法就表示切面中的通知,如文件3所示。

文件3 MyAspect.java

     package com.itheima.aspect;
     //切面類:可以存在多個通知Advice(即增強的方法)
     public class MyAspect {
         public void check_Permissions(){
             System.out.println("模擬檢查權限...");
         }
         public void log(){
             System.out.println("模擬記錄日志...");
         }
     }

(5)在com.itheima.jdk包下,創建代理類JdkProxy,該類需要實現InvocationHandler接口,并編寫代理方法。在代理方法中,需要通過Proxy類實現動態代理,如文件4所示。

文件4 JdkProxy.java

     package com.itheima.jdk;
     import java.lang.reflect.InvocationHandler;
     import java.lang.reflect.Method;
     import java.lang.reflect.Proxy;
     import com.itheima.aspect.MyAspect;
     /**
      * JDK代理類
      */
     public class JdkProxy implements InvocationHandler{
         // 聲明目標類接口
         private UserDao userDao;
         // 創建代理方法
         public  Object createProxy(UserDao userDao) {
             this.userDao = userDao;
             // 1.類加載器
             ClassLoader classLoader = JdkProxy.class.getClassLoader();
             // 2.被代理對象實現的所有接口
             Class[] clazz = userDao.getClass().getInterfaces();
             // 3.使用代理類,進行增強,返回的是代理后的對象
             return  Proxy.newProxyInstance(classLoader,clazz,this);
         }
         /*
          * 所有動態代理類的方法調用,都會交由invoke()方法去處理
          * proxy 被代理后的對象 
          * method 將要被執行的方法信息(反射) 
          * args 執行方法時需要的參數
          */
         @Override
         public Object invoke(Object proxy, Method method, Object[] args) 
                                                                     throws Throwable {
             // 聲明切面
             MyAspect myAspect = new MyAspect();
             // 前增強
             myAspect.check_Permissions();
             // 在目標類上調用方法,并傳入參數
             Object obj = method.invoke(userDao, args);
             // 后增強
             myAspect.log();
             return obj;
         }
     }

在文件4中,JdkProxy類實現了InvocationHandler接口,并實現了接口中的invoke()方法,所有動態代理類所調用的方法都會交由該方法處理。在創建的代理方法createProxy()中,使用了Proxy類的newProxyInstance()方法來創建代理對象。newProxyInstance()方法中包含三個參數,其中第1個參數是當前類的類加載器,第2個參數表示的是被代理對象實現的所有接口,第3個參數this代表的就是代理類JdkProxy本身。在invoke()方法中,目標類方法執行的前后,會分別執行切面類中的check_Permissions()方法和log()方法。

(6)在com.itheima.jdk包中,創建測試類JdkTest。在該類中的main()方法中創建代理對象和目標對象,然后從代理對象中獲得對目標對象userDao增強后的對象,最后調用該對象中的添加和刪除方法,如文件5所示。

文件5 JdkTest.java

     package com.itheima.jdk;
     public class JdkTest{
         public static void main(String[] args) {
             // 創建代理對象
             JdkProxy jdkProxy = new JdkProxy();
              // 創建目標對象
             UserDao userDao= new UserDaoImpl();
             // 從代理對象中獲取增強后的目標對象
             UserDao userDao1 = (UserDao) jdkProxy.createProxy(userDao);
             // 執行方法
             userDao1.addUser();
             userDao1.deleteUser();
         }
     }

執行程序后,控制臺的輸出結果如圖1所示。

JDK動態代理

圖1 運行結果

從圖1可以看出,userDao實例中的添加用戶和刪除用戶的方法已被成功調用,并且在調用前后分別增加了檢查權限和記錄日志的功能。這種實現了接口的代理方式,就是Spring中的JDK動態代理。





猜你喜歡:

JDK環境變量配置win10視頻教程【黑馬程序員】

兩種常用的動態代理方式

一文詳解Proxy動態代理的內部機制

jdk14視頻教程:jdk14詳細介紹

黑馬程序員Java培訓培訓

分享到:
在線咨詢 我要報名
和我們在線交談!