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

深入淺出講解Spring框架中AOP及動(dòng)態(tài)代理的應(yīng)用

 更新時(shí)間:2022年03月31日 10:55:09   作者:AOP  
在軟件業(yè),AOP為Aspect?Oriented?Programming的縮寫,意為:面向切面編程,通過預(yù)編譯方式和運(yùn)行期間動(dòng)態(tài)代理實(shí)現(xiàn)程序功能的統(tǒng)一維護(hù)的一種技術(shù)

一. Spring AOP

       面向切面編程(Aspect Oriented Programming,AOP)是軟件編程思想發(fā)展到一定階段的產(chǎn)物,是對面向?qū)ο缶幊?Object Oriented Programming,OOP)的有益補(bǔ)充, 目前已成為一種比較成熟的編程方式。AOP適用于具有橫向邏輯的場所,如訪問控制、事務(wù)管理、性能監(jiān)測等。

1. 傳統(tǒng)問題:

      在傳統(tǒng)的業(yè)務(wù)處理代碼中,通常都會進(jìn)行事務(wù)處理、日志記錄等操作。雖然OOP可以通過組合或者繼承的方式來達(dá)到代碼的重用,但是比如實(shí)現(xiàn)日志記錄時(shí),代碼還是會分散到不同的方法中。這樣就會存在一個(gè)問題,如果想要關(guān)閉某個(gè)功能或者修改時(shí),就必須要修改所有的相關(guān)方法。這不單單增加了開發(fā)人員的工作量,而且提高了代碼的出錯(cuò)率。

2. 問題的解決策略:

      為了解決這個(gè)問題,AOP思想隨之產(chǎn)生。AOP采取橫向抽取機(jī)制,將分散在各個(gè)方法中的重復(fù)代碼提取出來,然后在程序編譯或運(yùn)行時(shí),再將這些提取出來的代碼應(yīng)用到需要執(zhí)行的地方。這種采用橫向抽取機(jī)制的方式,是傳統(tǒng)的OOP思想無法辦到的,因?yàn)镺OP只能實(shí)現(xiàn)父子關(guān)系的縱向的重用。雖然AOP是一種新的編程思想,卻不是OOP的替代品,它只是OOP的延申和補(bǔ)充。

3. AOP優(yōu)點(diǎn):

       AOP的使用讓開發(fā)人員在編寫業(yè)務(wù)邏輯時(shí)可以專心于核心業(yè)務(wù),而不用過多地關(guān)注于其他業(yè)務(wù)邏輯的實(shí)現(xiàn),這不但提高了開發(fā)效率,而且增強(qiáng)了代碼的可維護(hù)性。

  在AOP思想中,類于切面的關(guān)系如下圖所示。我們可以看出,通過Aspect(切面)分別在Class1和Class2的方法中加入了事務(wù)、日志、權(quán)限和異常等功能。

 二. 動(dòng)態(tài)代理

      通過學(xué)習(xí)我們知道了AOP中的代理就是由AOP框架動(dòng)態(tài)生成的一個(gè)對象,該對象可以作為目標(biāo)對象使用,對于面向切面編程,簡單地說,就是在不改變原程序的基礎(chǔ)上為代碼段增加新的功能,對代碼段進(jìn)行增強(qiáng)處理。它的設(shè)計(jì)思想來源于代理設(shè)計(jì)模式,通常情況下調(diào)用對象的方法如下圖。

      在代理模式中可以為該對象設(shè)置一個(gè)代理對象,代理對象為function()提供一個(gè)代理方法,當(dāng)通過代理對象的function()方法調(diào)用原對象的function()方法時(shí),就可以在代理方法中添加新的功能,即增強(qiáng)處理。增強(qiáng)的功能既可以插到原對象的function()前面,也可以插到其后面(如虛線)

1. JDK動(dòng)態(tài)代理

      JDK動(dòng)態(tài)代理是通過java.lang.reflect.Proxy類來實(shí)現(xiàn)的,可以調(diào)用Proxy類的newProxyInstance()方法來創(chuàng)建代理對象。對于使用業(yè)務(wù)接口的類,Spring框架會默認(rèn)使用JDK動(dòng)態(tài)代理來實(shí)現(xiàn)AOP。通過一個(gè)案例來演示。

 1.  UserDao.java

package dao;
 
public interface UserDao {
    public void addUserDao();
    public void deleteUser();
}

2.  UserDaoImpl.java

package dao;
 
public class UserDaoImpl implements UserDao{
    @Override
    public void addUserDao() {
        System.out.println("添加用戶");
    }
 
    @Override
    public void deleteUser() {
        System.out.println("刪除用戶");
    }
}

3.  MyAspect.java

package aspect;
 
public class MyAspect {
    public void check_permission(){
        System.out.println("----模擬檢查訪問----");
    }
    public void log(){
        System.out.println("----模擬記錄日記----");
    }
}

4.  JdkProxy.java

package jdk;
 
import aspect.MyAspect;
import dao.UserDao;
 
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
/**
 * Jdk代理類
 */
public class JdkProxy implements InvocationHandler {
    //聲明目標(biāo)類接口
    private UserDao userdao;
//    創(chuàng)建代理方法
    public Object createProxy(UserDao userdao){
        this.userdao=userdao;
        //類加載器
        ClassLoader classLoader=JdkProxy.class.getClassLoader();
        //被代理對象實(shí)現(xiàn)的所有接口
        Class[] clazz=userdao.getClass().getInterfaces();
        //使用代理類進(jìn)行增強(qiáng),返回的是代理后的對象
        return Proxy.newProxyInstance(classLoader,clazz,this);
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //聲明切面
        MyAspect myAspect=new MyAspect();
        //前增強(qiáng)
        myAspect.check_permission();
        //在目標(biāo)上調(diào)用方法,并傳入?yún)?shù)
        Object obj=method.invoke(userdao,args);
        //后增強(qiáng)
        myAspect.log();
        return obj;
    }
}

5.  Test.java

    @Test
    public void shouldAnswerWithTrue()
    {
        JdkProxy jdkProxy=new JdkProxy();
        UserDao userDao=new UserDaoImpl();
        UserDao userDao1=(UserDao) jdkProxy.createProxy(userDao);
        userDao1.addUserDao();
        System.out.println("\n-----------------------------分割線------------------------------------\n");
        userDao1.deleteUser();
    }

結(jié)果:

2. CGLIB代理

     JDK 動(dòng)態(tài)代理的使用非常簡單,但它具有一定的局限性(使用動(dòng)態(tài)代理的對象必須實(shí)現(xiàn)一個(gè)或多個(gè)接口)如果要對沒有實(shí)現(xiàn)接口的類進(jìn)行代理,那么可以使用CGLIB代理。

         CGLIB(Code Generation Library)是一個(gè)高性能開源的代碼生成包,它采用非常底層的字節(jié)碼技術(shù),對指定的目標(biāo)類生成一個(gè)子類,并對子類進(jìn)行增強(qiáng)。在Spring框架的核心包中已經(jīng)集成了CGLIB所需要的包,所以開發(fā)中不需要另外導(dǎo)入jar包。

 1.  BookDao.java

package dao;
 
public class BookDao {
    public void addBook(){
        System.out.println("添加書本");
    }
    public void deleteBook(){
        System.out.println("刪除書本");
    }
}

2.  CglibProxy.java

package jdk;
 
 
import aspect.MyAspect;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
 
import java.lang.reflect.Method;
 
public class CglibProxy implements MethodInterceptor {
    //代理方法
    public Object createProxy(Object target){
        Enhancer enhancer=new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }
 
    @Override
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        MyAspect myAspect=new MyAspect();
        myAspect.check_permission();
        Object o1=methodProxy.invokeSuper(proxy,args);
        myAspect.log();
        return o1;
    }
}

結(jié)果:

到此這篇關(guān)于深入淺出講解Spring框架中AOP及動(dòng)態(tài)代理的應(yīng)用的文章就介紹到這了,更多相關(guān)Spring AOP及動(dòng)態(tài)代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot 接口開發(fā)教程(httpclient客戶端)

    SpringBoot 接口開發(fā)教程(httpclient客戶端)

    這篇文章主要介紹了SpringBoot 接口開發(fā)教程(httpclient客戶端),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java郵件發(fā)送的實(shí)現(xiàn)

    java郵件發(fā)送的實(shí)現(xiàn)

    本篇是用于java來實(shí)現(xiàn)郵件的發(fā)送的實(shí)例代碼,基于smtp服務(wù),有需要的可以參考一下。
    2016-10-10
  • springmvc+kindeditor文件上傳實(shí)例詳解

    springmvc+kindeditor文件上傳實(shí)例詳解

    這篇文章主要為大家詳細(xì)介紹了springmvc+kindeditor文件上傳實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-08-08
  • C++內(nèi)存管理看這一篇就夠了

    C++內(nèi)存管理看這一篇就夠了

    這篇文章主要介紹了C/C++中的內(nèi)存管理小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • springboot+camunda實(shí)現(xiàn)工作流的流程分析

    springboot+camunda實(shí)現(xiàn)工作流的流程分析

    Camunda是基于Java語言,支持BPMN標(biāo)準(zhǔn)的工作流和流程自動(dòng)化框架,并且還支持CMMN規(guī)范,DMN規(guī)范,本文給大家介紹springboot+camunda實(shí)現(xiàn)工作流的流程分析,感興趣的朋友一起看看吧
    2021-12-12
  • Java利用線程工廠監(jiān)控線程池的實(shí)現(xiàn)示例

    Java利用線程工廠監(jiān)控線程池的實(shí)現(xiàn)示例

    這篇文章主要介紹了Java利用線程工廠監(jiān)控線程池的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • java abstract class interface之間的區(qū)別介紹

    java abstract class interface之間的區(qū)別介紹

    含有abstract修飾符的class即為抽象類,abstract 類不能創(chuàng)建的實(shí)例對象,abstract class類中定義抽象方法必須在具體(Concrete)子類中實(shí)現(xiàn),所以,不能有抽象構(gòu)造方法或抽象靜態(tài)方法
    2012-11-11
  • Java?實(shí)戰(zhàn)項(xiàng)目之家政服務(wù)平臺系統(tǒng)的實(shí)現(xiàn)流程

    Java?實(shí)戰(zhàn)項(xiàng)目之家政服務(wù)平臺系統(tǒng)的實(shí)現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠(yuǎn)遠(yuǎn)不夠的,只有在實(shí)戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SSM+jsp+mysql+maven實(shí)現(xiàn)家政服務(wù)平臺系統(tǒng),大家可以在過程中查缺補(bǔ)漏,提升水平
    2021-11-11
  • java顯示當(dāng)前運(yùn)行時(shí)的參數(shù)(java運(yùn)行參數(shù))

    java顯示當(dāng)前運(yùn)行時(shí)的參數(shù)(java運(yùn)行參數(shù))

    這篇文章主要介紹了java顯示當(dāng)前運(yùn)行時(shí)參數(shù)的示例(java運(yùn)行參數(shù)),需要的朋友可以參考下
    2014-04-04
  • MyBatis實(shí)現(xiàn)動(dòng)態(tài)SQL的實(shí)現(xiàn)方法

    MyBatis實(shí)現(xiàn)動(dòng)態(tài)SQL的實(shí)現(xiàn)方法

    這篇文章主要介紹了MyBatis實(shí)現(xiàn)動(dòng)態(tài)SQL的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12

最新評論

南投市| 嵩明县| 武川县| 孝昌县| 长沙市| 雷波县| 富阳市| 贡山| 包头市| 龙川县| 沂水县| 亳州市| 江孜县| 图们市| 育儿| 韶山市| 永济市| 新宁县| 遂昌县| 徐闻县| 泰安市| 浙江省| 沙洋县| 巴林右旗| 平顺县| 北安市| 绥宁县| 施甸县| 木里| 修武县| 西乌珠穆沁旗| 永川市| 都江堰市| 拜泉县| 灌云县| 上杭县| 东阳市| 龙口市| 珲春市| 东宁县| 潞城市|