最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringAOP中的動態(tài)代理技術(shù)深入解析

 更新時間:2024年01月26日 10:24:33   作者:ThinkPet  
這篇文章主要介紹了SpringAOP中的動態(tài)代理技術(shù)深入解析,spring默認使用JDK動態(tài)代理實現(xiàn)AOP,類如果實現(xiàn)了接口,spring就會用JDK動態(tài)代理實現(xiàn)AOP,如果目標類沒有實現(xiàn)接口,spring則使用Cglib動態(tài)代理來實現(xiàn)AOP,需要的朋友可以參考下

動態(tài)代理

Spring的aop實現(xiàn)主要應(yīng)用了JDK動態(tài)代理和Cglib動態(tài)代理 這2種代理。

org.springframework.aop.framework.JdkDynamicAopProxy
org.springframework.aop.framework.CglibAopProxy

spring默認使用JDK動態(tài)代理實現(xiàn)AOP,類如果實現(xiàn)了接口,spring就會用JDK動態(tài)代理實現(xiàn)AOP. 如果目標類沒有實現(xiàn)接口,spring則使用Cglib動態(tài)代理來實現(xiàn)AOP.

  • jdk動態(tài)代理的優(yōu)勢:jdk自身支持,減少依賴,可隨jdk平滑升級,代碼實現(xiàn)簡單
  • cglib動態(tài)代理的優(yōu)勢:無需實現(xiàn)接口,達到無侵入,只操作我們關(guān)系的類,而不必為其他相關(guān)類增加工作量

spring事務(wù)便是基于spring aop實現(xiàn)的, spring事務(wù)的一些失效場景,如

1.使用了private方法,導致事務(wù)失效(被動態(tài)代理的方法必須是public)

2.使用了final方法,導致事務(wù)失效(如果方法定義為final,JDK動態(tài)代理和cglib動態(tài)代理無法重寫該方法)

3.同一類內(nèi)部方法調(diào)用:直接使用this對象調(diào)用方法,無法生成代理方法,導致事務(wù)失效

測試使用Cglib動態(tài)代理

定義被代理的方法

package cn.demo.cglib;
public class OrderService {
    /**
     * 被動態(tài)代理的方法應(yīng)該是public公共的
     * @param orderNo
     */
    public void order(String orderNo){
        System.out.println("order something...");
    }
}

定義cglib動態(tài)代理時觸發(fā)的攔截器

package cn.demo.cglib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 動態(tài)代理類,實現(xiàn)方法攔截器MethodInterceptor接口
 */
public class LogInterceptor implements MethodInterceptor {


    //cglib動態(tài)代理,基于ASM機制實現(xiàn),通過生成目標類的子類作為代理類
    //使用cglib中的Enhancer來生成代理對象子類,
    public Object getProxyInstance(Class targetClass){
        //1.工具類
        Enhancer enhancer = new Enhancer();
        //2.設(shè)置父類
        enhancer.setSuperclass(targetClass);
        //3.設(shè)置回調(diào)函數(shù)
        enhancer.setCallback(this);
        //4.創(chuàng)建子類(代理對象)
        return enhancer.create();


    }

    //并實現(xiàn)MethodInterceptor的intercept方法來實現(xiàn)增強功能
    @Override
    public Object intercept(Object o, Method method,
                            Object[] objects,
                            MethodProxy methodProxy) throws Throwable {

        System.out.println("LogInterceptor: Before invoke---");

        Object obj = methodProxy.invokeSuper(o,objects);

        System.out.println("LogInterceptor: After invoke---");

        return obj;
    }
}

使用cglib動態(tài)代理出的實例

package cn.demo.cglib;
public class CglibTest {
    public static void main(String[] args) {
        //Cglib動態(tài)代理特點
        //1.需要引入cglib依賴jar (一般spring的核心包已經(jīng)有了cglib依賴)
        //2.被代理的類不需要接口信息,Cglib動態(tài)代理可以攔截并包裝被代理類的所有方法
        //3.代理類要實現(xiàn)MethodInterceptor接口
        //4.代理類使用cglib中的Enhancer來生成目標對象子類
        //5.目標類不能為final,因為final類不能創(chuàng)建子類
        OrderService orderService = (OrderService)
                new LogInterceptor()
                        .getProxyInstance(OrderService.class);
        orderService.order("123");
    }
}

測試使用jdk動態(tài)代理

定義被代理的方法及其接口

package cn.demo.proxy;

public interface UserService {
    void login(String username, String password);
}

package cn.demo.proxy;
//jdk動態(tài)代理的致命缺點就是目標類必須實現(xiàn)某個接口
public class UserServiceImpl implements UserService{
    @Override
    public void login(String username, String password) {
        System.out.println("User Login Service!");
    }
}

定義jdk動態(tài)代理時觸發(fā)的攔截器

package cn.demo.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
//通過實現(xiàn)InvocationHandler接口完成代理邏輯
public class LogHandler implements InvocationHandler {
    /**
     * 被代理的對象,實際的方法執(zhí)行者
     */
    Object target;
    public LogHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //在函數(shù)invoke之前之后,可以進行一些自定義操作
        //如 日志、事務(wù)、攔截器、權(quán)限控制等
        System.out.println("Before Login ---");
        Object result = method.invoke(target,args);
        System.out.println("After Login ---");
        return result;
    }
}

使用jdk動態(tài)代理出的實例

package cn.demo.proxy;
import java.lang.reflect.Proxy;
public class JdkProxyTest {
    public static void main(String[] args) {
        //創(chuàng)建被代理的對象, UserService接口的實現(xiàn)類
        UserServiceImpl userService = new UserServiceImpl();
        //創(chuàng)建代理對象,包含3個參數(shù) ClassLoader 、 目標類實現(xiàn)接口數(shù)組、 事件處理器
        UserService userProxy = (UserService)
                Proxy.newProxyInstance(
                        userService.getClass().getClassLoader(),
                        userService.getClass().getInterfaces(),
                        new LogHandler(userService)
                );
         //用代理出的實例調(diào)用login方法
        userProxy.login("admin", "123456");
}

到此這篇關(guān)于SpringAOP中的動態(tài)代理技術(shù)深入解析的文章就介紹到這了,更多相關(guān)SpringAOP動態(tài)代理技術(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中使用SQLite數(shù)據(jù)庫的實現(xiàn)示例

    Java中使用SQLite數(shù)據(jù)庫的實現(xiàn)示例

    SQLite是一種嵌入式數(shù)據(jù)庫引擎,可以在各種平臺上使用,本文主要介紹了Java中使用SQLite數(shù)據(jù)庫的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-01-01
  • SpringAOP中的通知Advice解析

    SpringAOP中的通知Advice解析

    這篇文章主要介紹了SpringAOP中的通知Advice解析,AOP 中的通知是基于連接點業(yè)務(wù)邏輯的一種增強,Spring AOP 可以基于 XML 方式和基于注解方式定義,只是寫法不同,這里只使用注解的方式來講解通知的詳細用法,需要的朋友可以參考下
    2023-09-09
  • Java編程實現(xiàn)生成給定范圍內(nèi)不重復(fù)隨機數(shù)的方法小結(jié)

    Java編程實現(xiàn)生成給定范圍內(nèi)不重復(fù)隨機數(shù)的方法小結(jié)

    這篇文章主要介紹了Java編程實現(xiàn)生成給定范圍內(nèi)不重復(fù)隨機數(shù)的方法,結(jié)合實例形式總結(jié)分析了java基于數(shù)學運算與判斷實現(xiàn)不重復(fù)隨機數(shù)的生成功能,需要的朋友可以參考下
    2017-07-07
  • Java泛型機制的程序演示詳解

    Java泛型機制的程序演示詳解

    這篇文章主要為大家詳細介紹了Java泛型機制的程序演示,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • Java生成PDF文件的實例代碼

    Java生成PDF文件的實例代碼

    Java生成PDF文件的實例代碼,需要的朋友可以參考一下
    2013-05-05
  • Spring表達式語言SpEL用法詳解

    Spring表達式語言SpEL用法詳解

    這篇文章主要介紹了spring表達式語言SpEL用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-01-01
  • Java如何將ResultSet結(jié)果集遍歷到List中

    Java如何將ResultSet結(jié)果集遍歷到List中

    這篇文章主要介紹了Java如何將ResultSet結(jié)果集遍歷到List中問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 詳解Spring Boot 定制HTTP消息轉(zhuǎn)換器

    詳解Spring Boot 定制HTTP消息轉(zhuǎn)換器

    本篇文章主要介紹了詳解Spring Boot 定制HTTP消息轉(zhuǎn)換器,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • Spring常見錯誤之Web嵌套對象校驗失效解決辦法

    Spring常見錯誤之Web嵌套對象校驗失效解決辦法

    這篇文章主要介紹了Spring常見錯誤之Web嵌套對象校驗失效解決的相關(guān)資料,通過在Phone對象上添加@Valid注解,問題得以解決,需要的朋友可以參考下
    2025-01-01
  • Java基于面向?qū)ο髮崿F(xiàn)一個戰(zhàn)士小游戲

    Java基于面向?qū)ο髮崿F(xiàn)一個戰(zhàn)士小游戲

    這篇文章主要為大家詳細介紹了Java如何基于面向?qū)ο髮崿F(xiàn)一個戰(zhàn)士小游戲,文中的示例代碼講解詳細,感興趣的小伙伴可以動手嘗試一下
    2022-07-07

最新評論

九寨沟县| 隆回县| 元江| 龙川县| 甘肃省| 石首市| 唐海县| 新巴尔虎左旗| 祁东县| 华宁县| 雷山县| 内江市| 中宁县| 集安市| 睢宁县| 淳安县| 临漳县| 阿坝县| 高密市| 灵石县| 尼玛县| 波密县| 兰州市| 武义县| 泾阳县| 将乐县| 霍州市| 阳山县| 淳安县| 子长县| 驻马店市| 阜平县| 余干县| 乌苏市| 湛江市| 余江县| 绵竹市| 仙居县| 定陶县| 永年县| 寿阳县|