小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Spring的兩種動態(tài)代理:Jdk和Cglib 的區(qū)別和實現

 跑不動的豬 2020-03-24

一、原理區(qū)別:

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

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

1、如果目標對象實現了接口,默認情況下會采用JDK的動態(tài)代理實現AOP 
2、如果目標對象實現了接口,可以強制使用CGLIB實現AOP 

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

如何強制使用CGLIB實現AOP?
 (1)添加CGLIB庫,SPRING_HOME/cglib/*.jar
 (2)在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>

JDK動態(tài)代理和CGLIB字節(jié)碼生成的區(qū)別?
 (1)JDK動態(tài)代理只能對實現了接口的類生成代理,而不能針對類
 (2)CGLIB是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法
   因為是繼承,所以該類或方法最好不要聲明成final 

二、代碼實現

用戶管理接口

復制代碼

package com.lf.shejimoshi.proxy.entity;//用戶管理接口public interface UserManager {    //新增用戶抽象方法
    void addUser(String userName,String password);    //刪除用戶抽象方法
    void delUser(String userName);
    
}

復制代碼

用戶管理接口實現類

復制代碼

package com.lf.shejimoshi.proxy.entity;//用戶管理實現類,實現用戶管理接口public class UserManagerImpl implements UserManager{    //重寫新增用戶方法    @Override    public void addUser(String userName, String password) {
        System.out.println("調用了新增的方法!");
        System.out.println("傳入參數為 userName: "+userName+" password: "+password);
    }    //重寫刪除用戶方法    @Override    public void delUser(String userName) {
        System.out.println("調用了刪除的方法!");
        System.out.println("傳入參數為 userName: "+userName);
    }
    
}

復制代碼

JDK動態(tài)代理

復制代碼

package com.lf.shejimoshi.proxy.jdk;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.lf.shejimoshi.proxy.entity.UserManager;import com.lf.shejimoshi.proxy.entity.UserManagerImpl;//JDK動態(tài)代理實現InvocationHandler接口public class JdkProxy implements InvocationHandler {    private Object target ;//需要代理的目標對象    
    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("JDK動態(tài)代理,監(jiān)聽開始!");
        Object result = method.invoke(target, args);
        System.out.println("JDK動態(tài)代理,監(jiān)聽結束!");        return result;
    }    //定義獲取代理對象方法
    private Object getJDKProxy(Object targetObject){        //為目標對象target賦值
        this.target = targetObject;        //JDK動態(tài)代理只能針對實現了接口的類進行代理,newProxyInstance 函數所需參數就可看出
        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);
    }    
    public static void main(String[] args) {
        JdkProxy jdkProxy = new JdkProxy();//實例化JDKProxy對象
        UserManager user = (UserManager) jdkProxy.getJDKProxy(new UserManagerImpl());//獲取代理對象
        user.addUser("admin", "123123");//執(zhí)行新增方法    }
    
}

復制代碼

JDK動態(tài)代理運行結果

Cglib動態(tài)代理(需要導入兩個jar包,asm-5.2.jar,cglib-3.2.5.jar。版本自行選擇)

復制代碼

package com.lf.shejimoshi.proxy.cglib;import java.lang.reflect.Method;import com.lf.shejimoshi.proxy.entity.UserManager;import com.lf.shejimoshi.proxy.entity.UserManagerImpl;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;//Cglib動態(tài)代理,實現MethodInterceptor接口public class CglibProxy implements MethodInterceptor {    private Object target;//需要代理的目標對象    
    //重寫攔截方法    @Override    public Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {
        System.out.println("Cglib動態(tài)代理,監(jiān)聽開始!");
        Object invoke = method.invoke(target, arr);//方法執(zhí)行,參數:target 目標對象 arr參數數組
        System.out.println("Cglib動態(tài)代理,監(jiān)聽結束!");        return invoke;
    }    //定義獲取代理對象方法
    public Object getCglibProxy(Object objectTarget){        //為目標對象target賦值
        this.target = objectTarget;
        Enhancer enhancer = new Enhancer();        //設置父類,因為Cglib是針對指定的類生成一個子類,所以需要指定父類        enhancer.setSuperclass(objectTarget.getClass());
        enhancer.setCallback(this);// 設置回調 
        Object result = enhancer.create();//創(chuàng)建并返回代理對象
        return result;
    }    
    public static void main(String[] args) {
        CglibProxy cglib = new CglibProxy();//實例化CglibProxy對象
        UserManager user =  (UserManager) cglib.getCglibProxy(new UserManagerImpl());//獲取代理對象
        user.delUser("admin");//執(zhí)行刪除方法    }
    
}

復制代碼

Cglib動態(tài)代理運行結果

    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多