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

Spring?AOP原理及動態(tài)代理

 更新時間:2022年09月21日 09:41:57   作者:IT小郭.  
這篇文章主要介紹了Spring?AOP原理及動態(tài)代理,文章通過圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的小伙伴可以參考一下

一、什么是代理?

指為一個目標對象提供一個代理對象, 并由代理對象控制對目標對象的引用. 使用代理對象, 是為了在不修改目標對象的基礎上,增強目標對象的業(yè)務邏輯.

1、靜態(tài)代理

靜態(tài)代理的特點是, 為每一個業(yè)務增強都提供一個代理類, 由代理類來創(chuàng)建代理對象. 下面我們通過靜態(tài)代理來實現(xiàn)對轉賬業(yè)務進行身份驗證.

(1) 轉賬業(yè)務

public interface IAccountService {
    //主業(yè)務邏輯: 轉賬
    void transfer();
}

public class AccountServiceImpl implements IAccountService {
    @Override
    public void transfer() {
        System.out.println("調用dao層,完成轉賬主業(yè)務.");
    }
}

(2) 代理類

public class AccountProxy implements IAccountService {
    //目標對象
    private IAccountService target;
    public AccountProxy(IAccountService target) {
        this.target = target;
    }
    /**
     * 代理方法,實現(xiàn)對目標方法的功能增強
     */
    @Override
    public void transfer() {
        before();
        target.transfer();
    }
    /**
     * 前置增強
     */
    private void before() {
        System.out.println("對轉賬人身份進行驗證.");
    }
}

(3) 測試

public class Client {
    public static void main(String[] args) {
        //創(chuàng)建目標對象
        IAccountService target = new AccountServiceImpl();
        //創(chuàng)建代理對象
        AccountProxy proxy = new AccountProxy(target);
        proxy.transfer();
    }
}

結果: 對轉賬人身份進行驗證.調用dao層,完成轉賬主業(yè)務.

2、動態(tài)代理

靜態(tài)代理會為每一個業(yè)務增強都提供一個代理類, 由代理類來創(chuàng)建代理對象, 而動態(tài)代理并不存在代理類, 代理對象直接由代理生成工具動態(tài)生成.

2.1、JDK動態(tài)代理

JDK動態(tài)代理是使用 java.lang.reflect 包下的代理類來實現(xiàn). JDK動態(tài)代理動態(tài)代理必須要有接口.

(1) 轉賬業(yè)務

public interface IAccountService {
    //主業(yè)務邏輯: 轉賬
    void transfer();
}
public class AccountServiceImpl implements IAccountService {
    @Override
    public void transfer() {
        System.out.println("調用dao層,完成轉賬主業(yè)務.");
    }
}

(2) 增強

因為這里沒有配置切入點, 稱為切面會有點奇怪, 所以稱為增強.

public class AccountAdvice implements InvocationHandler {
    //目標對象
    private IAccountService target;

    public AccountAdvice(IAccountService target) {
        this.target = target;
    }

    /**
     * 代理方法, 每次調用目標方法時都會進到這里
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        return method.invoke(target, args);
    }

    /**
     * 前置增強
     */
    private void before() {
        System.out.println("對轉賬人身份進行驗證.");
    }
}

(3) 測試

public class Client {
    public static void main(String[] args) {
        //創(chuàng)建目標對象
        IAccountService target = new AccountServiceImpl();
        //創(chuàng)建代理對象
        IAccountService proxy = (IAccountService) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new AccountAdvice(target)
        );
        proxy.transfer();
    }
}

結果: 對轉賬人身份進行驗證.調用dao層,完成轉賬主業(yè)務.

2.2、 CGLIB動態(tài)代理

JDK動態(tài)代理必須要有接口, 但如果要代理一個沒有接口的類該怎么辦呢? 這時我們可以使用CGLIB動態(tài)代理. CGLIB動態(tài)代理的原理是生成目標類的子類, 這個子類對象就是代理對象, 代理對象是被增強過的.

注意: 不管有沒有接口都可以使用CGLIB動態(tài)代理, 而不是只有在無接口的情況下才能使用

(1) 轉賬業(yè)務

public class AccountService {
    public void transfer() {
        System.out.println("調用dao層,完成轉賬主業(yè)務.");
    }
}

(2) 增強

因為這里沒有配置切入點, 稱為切面會有點奇怪, 所以稱為增強.

public class AccountAdvice implements MethodInterceptor {
    /**
     * 代理方法, 每次調用目標方法時都會進到這里
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        before();
        return methodProxy.invokeSuper(obj, args);
        //        return method.invoke(obj, args);  這種也行
    }

    /**
     * 前置增強
     */
    private void before() {
        System.out.println("對轉賬人身份進行驗證.");
    }
}

(3) 測試

public class Client {
    public static void main(String[] args) {
        //創(chuàng)建目標對象
        AccountService target = new AccountService();
        //
        //創(chuàng)建代理對象
        AccountService proxy = (AccountService) Enhancer.create(target.getClass(),
                new AccountAdvice());
        proxy.transfer();
    }
}

結果: 對轉賬人身份進行驗證.調用dao層,完成轉賬主業(yè)務.

二、模擬Spring AOP場景

了解了動態(tài)代理后, 我們就可以自己來實現(xiàn)Spring AOP功能了, 所以下面我們來模擬下Spring AOP場景.

(1) 轉賬業(yè)務

public interface IAccountService {
    //主業(yè)務邏輯: 轉賬
    void transfer();
}
public class AccountServiceImpl implements IAccountService {
    @Override
    public void transfer() {
        System.out.println("調用dao層,完成轉賬主業(yè)務.");
    }
}

(2) 切面抽象類

定義一個切面抽象類, 該類使用了模板方法的設計模式, 為開始, 結束, 異常, 前置增強, 后置增強提供了默認實現(xiàn), 當我們定義切面類時只需要按需重寫它們就行. isIntercept() 方法用來判斷切入點是否正確, 切面類需要重寫這個方法.

public abstract class BaseAspect implements MethodInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(BaseAspect.class);

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object result = null;

        begin();
        try {
            if (isIntercept(method, args)) {
                before();
                result = methodProxy.invokeSuper(obj, args);
                after();
            } else {
                result = methodProxy.invokeSuper(obj,args);
            }
        } catch (Exception e) {
            logger.error("proxy failure", e);
            error(e);
            throw e;
        } finally {
            end();
        }
        return result;
    }
    /**
     * 開始增強
     */
    public void begin() {
    }
    /**
     * 切入點判斷
     */
    public boolean isIntercept(Method method, Object[] args) throws Throwable {
        return true;
    }
    /**
     * 前置增強
     */
    public void before() throws Throwable {
    }

    /**
     * 后置增強
     */
    public void after() throws Throwable {
    }

    /**
     * 異常增強
     */
    public void error(Throwable e) {
    }

    /**
     * 最終增強
     */
    public void end() {
    }
}

(3) 切面類

創(chuàng)建一個切面類, 類中配置切入點和增強.

public class AccountAspect extends BaseAspect {
    /**
     * 切入點
     */
    public boolean isIntercept(Method method, Object[] args) throws Throwable {
        return method.getName().equals("transfer");
    }

    /**
     * 前置增強
     */
    public void before() throws Throwable {
        System.out.println("對轉賬人身份進行驗證.");
    }
}

(4) 代理工廠類

定義一個工廠類來創(chuàng)建代理, 其實不創(chuàng)建這個類也行, 但為了模仿Spring還是創(chuàng)建了. @SuppressWarnings是為了抑制警告, 就是編譯器上面的黃線.

public class ProxyFactory {

    @SuppressWarnings("unchecked")
    public static <T> T createProxy(final Class<?> targetClass, final MethodInterceptor methodInterceptor) {
        return (T) Enhancer.create(targetClass,methodInterceptor);
    }
}

(5) 測試

public class Client {
    public static void main(String[] args) {
        //創(chuàng)建目標對象
        IAccountService target = new AccountServiceImpl();
        //切面
        BaseAspect accountAspect = new AccountAspect();
        //創(chuàng)建代理對象
        IAccountService proxy = (IAccountService) ProxyFactory.createProxy(target.getClass(), accountAspect);
        proxy.transfer();
    }
}

結果:對轉賬人身份進行驗證.調用dao層,完成轉賬主業(yè)務.

到此這篇關于Spring AOP原理及動態(tài)代理的文章就介紹到這了,更多相關Spring AOP 內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解Maven 搭建spring boot多模塊項目(附源碼)

    詳解Maven 搭建spring boot多模塊項目(附源碼)

    這篇文章主要介紹了詳解Maven 搭建spring boot多模塊項目(附源碼),具有一定的參考價值,有興趣的可以了解一下
    2017-09-09
  • 詳解設計模式在Spring中的應用(9種)

    詳解設計模式在Spring中的應用(9種)

    這篇文章主要介紹了詳解設計模式在Spring中的應用(9種),詳細的介紹了這9種模式在項目中的應用,具有一定的參考價值,感興趣的可以了解一下
    2019-04-04
  • Java中Excel高效解析工具EasyExcel的實踐

    Java中Excel高效解析工具EasyExcel的實踐

    EasyExcel是阿里巴巴開源的一個excel處理框架,已使用簡單,節(jié)省內存著稱,下面這篇文章主要給大家介紹了關于Java中Excel高效解析工具EasyExcel實踐的相關資料,需要的朋友可以參考下
    2022-04-04
  • java 使用過濾器實現(xiàn)登錄攔截處理

    java 使用過濾器實現(xiàn)登錄攔截處理

    這篇文章主要介紹了java 使用過濾器實現(xiàn)登錄攔截處理方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Spring AOP 自定義注解的實現(xiàn)代碼

    Spring AOP 自定義注解的實現(xiàn)代碼

    本篇文章主要介紹了Spring AOP 自定義注解的實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • 詳解Gradle安裝并配置到IDEA的方法

    詳解Gradle安裝并配置到IDEA的方法

    這篇文章主要介紹了Gradle安裝并配置到IDEA的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-09-09
  • HttpClient的KeepAlive接口方法源碼解析

    HttpClient的KeepAlive接口方法源碼解析

    這篇文章主要為大家介紹了HttpClient的KeepAlive接口方法源碼解析,
    有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-10-10
  • Java中的MultipartFile接口和File類解讀

    Java中的MultipartFile接口和File類解讀

    本文主要介紹了Java中的File類和Spring框架中的MultipartFile接口,File類提供了對文件和目錄操作的方法,如創(chuàng)建、刪除、重命名、判斷文件是否存在等,MultipartFile接口用于處理文件上傳,提供了獲取上傳文件信息和保存上傳文件的方法
    2025-02-02
  • Java 位圖法排序的使用方法

    Java 位圖法排序的使用方法

    本篇文章,小編將為大家介紹關于Java 位圖法排序的使用方法,有需要的朋友可以參考一下
    2013-04-04
  • 一文搞懂Java?JDBC中的SQL注入問題

    一文搞懂Java?JDBC中的SQL注入問題

    在用戶輸入的數據中有SQL關鍵字或語法,并且關鍵字或語法參與了SQL語句的編譯,導致SQL語句編譯后的條件為true,一直得到正確的結果,這種現(xiàn)象就是SQL注入,這篇文章主要介紹了一文搞懂Java?JDBC中的SQL注入問題,需要的朋友可以參考下
    2022-10-10

最新評論

兰考县| 余庆县| 宁武县| 什邡市| 铁岭县| 错那县| 上犹县| 正定县| 米脂县| 台中市| 炎陵县| 蓝山县| 眉山市| 山丹县| 安泽县| 屯留县| 盘山县| 三河市| 涞源县| 襄城县| 淮滨县| 深泽县| 江城| 东平县| 措勤县| 闽清县| 台湾省| 高尔夫| 洛隆县| 兴安盟| 张家川| 孙吴县| 游戏| 昌吉市| 太康县| 双城市| 石景山区| 万宁市| 蓝田县| 达州市| 汉源县|