91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring中JDK與CGLIB有什么不同

發布時間:2020-11-12 16:48:59 來源:億速云 閱讀:118 作者:Leah 欄目:編程語言

Spring中JDK與CGLIB有什么不同?很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。

一、原理區別:

Java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。

而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

1、如果目標對象實現了接口,默認情況下會采用JDK的動態代理實現AOP

2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP

3、如果目標對象沒有實現了接口,必須采用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換

如何強制使用CGLIB實現AOP?

(1)添加CGLIB庫,SPRING_HOME/cglib/.jar

(2)在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>

JDK動態代理和CGLIB字節碼生成的區別?

(1)JDK動態代理只能對實現了接口的類生成代理,而不能針對類

 (2)CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法

因為是繼承,所以該類或方法最好不要聲明成final

二、代碼實現

package com.fy.spring.proxy;    
public interface UserManager {  
  public void addUser(String id, String password);  
  public void delUser(String id);  
}  
package com.fy.spring.proxy;  
  public class UserManagerImpl implements UserManager {  
  
  public void addUser(String id, String password) {  
    System.out.println(".: 掉用了UserManagerImpl.addUser()方法! ");  
  
  }  
  
  public void delUser(String id) {  
    System.out.println(".: 掉用了UserManagerImpl.delUser()方法! ");  
  
  }  
}  

JDK動態代理類

package com.fy.spring.proxy;  
import java.lang.reflect.InvocationHandler;  
import java.lang.reflect.Method;  
import java.lang.reflect.Proxy;  
/**  
 *  
 * JDK動態代理類  
 *  
 *  
 */ 
public class JDKProxy implements InvocationHandler {  
  
  private Object targetObject;//需要代理的目標對象  
  
  public Object newProxy(Object targetObject) {//將目標對象傳入進行代理  
    this.targetObject = targetObject;   
    return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
        targetObject.getClass().getInterfaces(), this);//返回代理對象  
  }  
  
  public Object invoke(Object proxy, Method method, Object[] args)//invoke方法  
      throws Throwable {  
    checkPopedom();//一般我們進行邏輯處理的函數比如這個地方是模擬檢查權限  
    Object ret = null;   // 設置方法的返回值  
    ret = method.invoke(targetObject, args);    //調用invoke方法,ret存儲該方法的返回值  
    return ret;  
  }  
  
  private void checkPopedom() {//模擬檢查權限的例子  
    System.out.println(".:檢查權限 checkPopedom()!");  
  }  
}  

CGLibProxy動態代理類

package com.fy.spring.proxy;    
import java.lang.reflect.Method;  
  
import net.sf.cglib.proxy.Enhancer;  
import net.sf.cglib.proxy.MethodInterceptor;  
import net.sf.cglib.proxy.MethodProxy;  
  
/**  
 * CGLibProxy動態代理類的實例  
 *   
 *  
 */ public class CGLibProxy implements MethodInterceptor {  
  
  private Object targetObject;// CGLib需要代理的目標對象  
  
  public Object createProxyObject(Object obj) {  
    this.targetObject = obj;  
    Enhancer enhancer = new Enhancer();  
    enhancer.setSuperclass(obj.getClass());  
    enhancer.setCallback(this);  
    Object proxyObj = enhancer.create();  
    return proxyObj;// 返回代理對象  
  }  
  
  public Object intercept(Object proxy, Method method, Object[] args,  
      MethodProxy methodProxy) throws Throwable {  
    Object obj = null;  
    if ("addUser".equals(method.getName())) {// 過濾方法  
      checkPopedom();// 檢查權限  
    }  
    obj = method.invoke(targetObject, args);  
    return obj;  
  }  
  
  private void checkPopedom() {  
    System.out.println(".:檢查權限 checkPopedom()!");  
  }  
}  

測試類:

public class Client {  
  
  public static void main(String[] args) {  
  
    UserManager userManager = (UserManager) new CGLibProxy()  
        .createProxyObject(new UserManagerImpl());  
    System.out.println("-----------CGLibProxy-------------");  
    userManager.addUser("tom", "root");  
    System.out.println("-----------JDKProxy-------------");  
    JDKProxy jdkPrpxy = new JDKProxy();  
    UserManager userManagerJDK = (UserManager) jdkPrpxy  
        .newProxy(new UserManagerImpl());  
    userManagerJDK.addUser("tom", "root");  
  }  
  
}  

運行結果:

-----------CGLibProxy-------------   
檢查權限  checkPopedom()!   
掉用了UserManagerImpl.addUser()方法!    
-----------JDKProxy-------------   
檢查權限  checkPopedom()!   
掉用了UserManagerImpl.addUser()方法! 

JDK代理是不需要以來第三方的庫,只要要JDK環境就可以進行代理,它有幾個要求

  1.  實現InvocationHandler
  2.  使用Proxy.newProxyInstance產生代理對象
  3.  被代理的對象必須要實現接口

CGLib 必須依賴于CGLib的類庫,但是它需要類來實現任何接口代理的是指定的類生成一個子類,覆蓋其中的方法,是一種繼承但是針對接口編程的環境下推薦使用JDK的代理

在Hibernate中的攔截器其實現考慮到不需要其他接口的條件Hibernate中的相關代理采用的是CGLib來執行。

看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

峨边| 谢通门县| 罗甸县| 定日县| 饶阳县| 兰考县| 新兴县| 新密市| 肇源县| 海晏县| 南岸区| 巢湖市| 民丰县| 桐乡市| 澎湖县| 兰溪市| 绥江县| 双鸭山市| 施甸县| 吉木萨尔县| 龙江县| 河南省| 武山县| 故城县| 芜湖县| 汤阴县| 枝江市| 贵溪市| 射阳县| 鄂托克前旗| 竹山县| 九江县| 广昌县| 新巴尔虎左旗| 安图县| 鸡泽县| 米易县| 玉环县| 淳化县| 灌云县| 黔西县|