国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring-AOP(面向切面)

這篇具有很好參考價值的文章主要介紹了Spring-AOP(面向切面)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Spring-AOP(面向切面)

場景模擬(計算器)

功能接口

public interface Calculator {
    int add(int i, int j);
    int minus(int i, int j);
    int multiply(int i, int j);
    int div(int i, int j);
}

實現(xiàn)類

public class CalculateLogImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        System.out.println("[日志]add方法開始,參數(shù)是"+ i+" " + j);
        int result = i + j;
        System.out.println("方法內(nèi)部:resultAdd = " + result);
        System.out.println("[日志]add方法結(jié)束,結(jié)果是:" + result);
        return result;
    }

    @Override
    public int minus(int i, int j) {
        System.out.println("[日志]minus 方法開始,參數(shù)是"+ i+" " + j);
        int result = i - j;
        System.out.println("方法內(nèi)部:resultMinus = " + result);
        System.out.println("[日志]minus 方法結(jié)束,結(jié)果是:" + result);
        return result;

    }

    @Override
    public int multiply(int i, int j) {
        System.out.println("[日志]multiply 方法開始,參數(shù)是"+ i+" " + j);
        int result = i * j;
        System.out.println("方法內(nèi)部:resultMultiply = " + result);
        System.out.println("[日志]multiply 方法結(jié)束,結(jié)果是:" + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        System.out.println("[日志]div 方法開始,參數(shù)是"+ i+" " + j);
        int result = i / j;
        System.out.println("方法內(nèi)部:resultDiv = " + result);
        System.out.println("[日志]div 方法結(jié)束,結(jié)果是:" + result);
        return result;
    }
}

在含有日志輸出的實現(xiàn)類中可以了解到:與核心業(yè)務功能沒有關(guān)系的日志輸出加雜在模塊中,對核心業(yè)務功能有干擾。

思路:解耦,將附加功能從業(yè)務功能模塊中抽取出來

代理模式

概念

二十三種設計模式中的一種,屬于結(jié)構(gòu)型模式,它的作用就是通過提供一個代理類,讓我們在調(diào)用目標方法時,不再直接對目標方法進行調(diào)用,而是通過代理類間接調(diào)用。讓不屬于目標方法核心邏輯的代碼從目標方法中剝離出來(解耦)。調(diào)用目標方法時先調(diào)用代理對象的方法,減少對目標方法的調(diào)用和打擾,同時讓附加功能能夠集中起來便于管理。

靜態(tài)代理

目標對象
接口
public interface Calculator {
    int add(int i, int j);
    int minus(int i, int j);
    int multiply(int i, int j);
    int div(int i, int j);
}
實現(xiàn)類
public class CalculatorImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        int result = i + j;
        System.out.println("方法內(nèi)部:resultAdd = " + result);
        return result;
    }

    @Override
    public int minus(int i, int j) {
        int result = i - j;
        System.out.println("方法內(nèi)部:resultMinus = " + result);
        return result;

    }

    @Override
    public int multiply(int i, int j) {
        int result = i * j;
        System.out.println("方法內(nèi)部:resultMultiply = " + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        System.out.println("方法內(nèi)部:resultDiv = " + result);
        return result;
    }
}
代理類
public class CalculatorStaticProxy implements Calculator {
    //被代理的目標對象傳遞過來
    private Calculator calculator;

    public CalculatorStaticProxy(Calculator calculator) {
        this.calculator = calculator;
    }

    @Override
    public int add(int i, int j) {
        System.out.println("[日志]add方法開始,參數(shù)是"+ i+" " + j);
        //調(diào)用目標對象的方法實現(xiàn)核心業(yè)務
        int result = calculator.add(i, j);
        System.out.println("[日志]add方法結(jié)束,結(jié)果是:" + result);
        return result;
    }

    @Override
    public int minus(int i, int j) {
        System.out.println("[日志]minus 方法開始,參數(shù)是"+ i+" " + j);
        int result = calculator.minus(i, j);
        System.out.println("[日志]minus 方法結(jié)束,結(jié)果是:" + result);
        return result;
    }

    @Override
    public int multiply(int i, int j) {
        System.out.println("[日志]multiply 方法開始,參數(shù)是"+ i+" " + j);
        int result = calculator.multiply(i,j);
        System.out.println("[日志]multiply 方法結(jié)束,結(jié)果是:" + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        System.out.println("[日志]div 方法開始,參數(shù)是"+ i+" " + j);
        int result = calculator.div(i, j);
        System.out.println("[日志]div 方法結(jié)束,結(jié)果是:" + result);
        return result;
    }
}
測試
@Test
public void testStaticProxy(){
    Calculator calculator = new CalculatorStaticProxy(new CalculatorImpl());
    calculator.add(10, 5);
    System.out.println("-------------------");
    calculator.minus(10, 5);
    System.out.println("-------------------");
    calculator.multiply(10, 5);
    System.out.println("-------------------");
    calculator.div(10, 5);
}

/*
*   [日志]add方法開始,參數(shù)是10 5
    方法內(nèi)部:resultAdd = 15
    [日志]add方法結(jié)束,結(jié)果是:15
    -------------------
    [日志]minus 方法開始,參數(shù)是10 5
    方法內(nèi)部:resultMinus = 5
    [日志]minus 方法結(jié)束,結(jié)果是:5
    -------------------
    [日志]multiply 方法開始,參數(shù)是10 5
    方法內(nèi)部:resultMultiply = 50
    [日志]multiply 方法結(jié)束,結(jié)果是:50
    -------------------
    [日志]div 方法開始,參數(shù)是10 5
    方法內(nèi)部:resultDiv = 2
    [日志]div 方法結(jié)束,結(jié)果是:2
* */

靜態(tài)代理類實現(xiàn)了解耦,但是由于代理類的代碼都是寫死的,就不具備復用的功能,在其他類需要相同功能的類需要進行代理時,也需要重新寫代理類,增加了代碼冗余,解決這一問題需要使用到動態(tài)代理方法。

動態(tài)代理

Spring-AOP(面向切面),Spring,spring,java,后端

Proxy工具類
public class ProxyUtil {
    //目標對象
    private Object target;

    public ProxyUtil(Object target) {
        this.target = target;
    }

    //反回代理對象
    public Object getProxy(){
        //使用Proxy中的newProxyInstance()
        /**
         * Proxy.newProxyInstance()
         * ClassLoader:加載動態(tài)生成代理類的類加載器
         * Class<?>[] interfaces:目標對象實現(xiàn)的所有接口的class類型數(shù)組
         * InvocationHandler:設置代理對象實現(xiàn)目標對象方法的過程
         */
        //ClassLoader:加載動態(tài)生成代理類的類加載器
        ClassLoader classLoader = target.getClass().getClassLoader();
        //Class<?>[] interfaces:目標對象實現(xiàn)的所有接口的class類型數(shù)組
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //InvocationHandler:設置代理對象實現(xiàn)目標對象方法的過程
        InvocationHandler invocationHandler = new InvocationHandler(){
            /**
             *
             * @param proxy :代理對象
             * @param method :需要重寫目標對象的方法
             * @param args:method方法中的參數(shù)
             * @return
             * @throws Throwable
             */
            @Override
            public Object invoke(Object proxy,
                                 Method method,
                                 Object[] args) throws Throwable {
                System.out.println("[動態(tài)代理][日志]" + method.getName() + ", 參數(shù):" + Arrays.toString(args));
                //調(diào)用目標的方法
                Object result = method.invoke(target, args);
                System.out.println("[動態(tài)代理][日志]" + method.getName() + ", 結(jié)果:" + result);
                return result;
            }
        };
        return Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }
}
測試類
@Test
public void testProxy(){
    //動態(tài)創(chuàng)建代理對象
    ProxyUtil proxyUtil = new ProxyUtil(new CalculatorImpl());
    Calculator proxy = (Calculator) proxyUtil.getProxy();
    proxy.add(1, 2);
    System.out.println("---------");
    proxy.minus(1, 2);
    System.out.println("---------");
    proxy.multiply(1, 2);
    System.out.println("---------");
    proxy.div(1, 2);
}



/*
*   [動態(tài)代理][日志]add, 參數(shù):[1, 2]
    方法內(nèi)部:resultAdd = 3
    [動態(tài)代理][日志]add, 結(jié)果:3
    ---------
    [動態(tài)代理][日志]minus, 參數(shù):[1, 2]
    方法內(nèi)部:resultMinus = -1
    [動態(tài)代理][日志]minus, 結(jié)果:-1
    ---------
    [動態(tài)代理][日志]multiply, 參數(shù):[1, 2]
    方法內(nèi)部:resultMultiply = 2
    [動態(tài)代理][日志]multiply, 結(jié)果:2
    ---------
    [動態(tài)代理][日志]div, 參數(shù):[1, 2]
    方法內(nèi)部:resultDiv = 0
    [動態(tài)代理][日志]div, 結(jié)果:0
* */

AOP概念及相關(guān)術(shù)語

簡介

AOP(Aspect Oriented Programming)是一種設計思想,是軟件設計領域中的面向切面編程,它是面向?qū)ο缶幊痰囊环N補充和完善,它以通過預編譯的方式和運行期動態(tài)代理方式實現(xiàn),在不修改源碼的情況下,給程序動態(tài)統(tǒng)一添加額外功能的一種技術(shù)。利用AOP可以對業(yè)務邏輯的各個部分進行隔離,從而使得業(yè)務邏輯各個部分之間的耦合度降低,提高程序的可重用性,提高開發(fā)效率。

相關(guān)術(shù)語

橫切關(guān)注點

分散在各個模塊中解決同一問題,如用戶驗證、日志管理、事務處理、事務緩存都屬于橫切關(guān)注點
從每個方法中抽取出來的同一類非核心業(yè)務。在同一個項目中,我們可以使用多個橫切關(guān)注點對相關(guān)方法進行多個方面的增強。這個概念不是語法層面的,而是根據(jù)附加功能的邏輯上的需要:有十個附加功能,就有十個橫切關(guān)注點。

Spring-AOP(面向切面),Spring,spring,java,后端

通知(增強)

增強,就是想要增強的功能,比如:安全、事務、日志等。每一個橫切關(guān)注點上要做的事情都需要寫一個方法來實現(xiàn),這樣的方法就叫通知方法。

前置通知:在被代理的目標方法前執(zhí)行
返回通知:在被代理的目標方法成功結(jié)束后執(zhí)行(壽終正寢)
異常通知:在被代理的目標方法異常結(jié)束后執(zhí)行(死于非命)
后置通知:在被代理的目標方法最終結(jié)束后執(zhí)行(蓋棺定論)
環(huán)繞通知:使用try...catch...finally結(jié)構(gòu)圍繞整個被代理的目標方法,包括上面四種通知對應的所有位置。

Spring-AOP(面向切面),Spring,spring,java,后端

切面

封裝通知方法的類。

Spring-AOP(面向切面),Spring,spring,java,后端

目標

被代理的目標對象。

代理

向目標對象應用通知之后創(chuàng)建的代理對象

連接點

這也是一個邏輯概念,不是語法定義的。把方法排成一排,每一個橫切位置看成x軸方向,把方法從上到下執(zhí)行的順序看成y軸,x軸和y軸的交叉點就是連接點。也就是spring允許使用通知的地方。

切入點

定位連接點的方式,每個類的方法中都包含多個連接點,如果把連接點看作數(shù)據(jù)庫中的記錄,那么切入點就是查詢記錄的SQL語句。Spring 的AOP技術(shù)可以通過切入點定位到特定的連接點,即可以使用增強方法的位置。

切入點通過org.springframework.aop.Pointcut接口進行描述,它使用類和方法作為連接點的查詢條件。

作用

簡化代碼:把方法中固定位置的重復代碼抽取出來,讓抽取的方法更專注于自己的核心功能,提高內(nèi)聚性。
代碼增強:把特定的功能封裝到切面類中,看哪里有需要,就往上套,被套用了切面邏輯的方法就被切面給增強了


基于注解的AOP

Spring-AOP(面向切面),Spring,spring,java,后端

AspectJ:是AOP思想的一種實現(xiàn)。本質(zhì)上是靜態(tài)代理,將代理邏輯"植入"被代理的目標,編譯得到的字節(jié)碼文件,所以最終效果是動態(tài)的。weaver就是植入器。Spring只是借用了AspectJ中的注解。

動態(tài)代理分類

JDK動態(tài)代理:有接口,生成接口實現(xiàn)類代理對象,代理對象和目標對象都實現(xiàn)同樣的接口。
cglib動態(tài)代理:沒有接口,繼承目標類,生成子類代理對象

準備工作
引入相關(guān)的依賴
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.0.9</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>6.0.9</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>6.0.9</version>
</dependency>
創(chuàng)建目標資源

接口

public interface Calculator {
    int add(int i, int j);
    int minus(int i, int j);
    int multiply(int i, int j);
    int div(int i, int j);
}

實現(xiàn)類

public class CalculatorImpl implements Calculator {
    @Override
    public int add(int i, int j) {
        int result = i + j;
        System.out.println("方法內(nèi)部:resultAdd = " + result);
        return result;
    }

    @Override
    public int minus(int i, int j) {
        int result = i - j;
        System.out.println("方法內(nèi)部:resultMinus = " + result);
        return result;

    }

    @Override
    public int multiply(int i, int j) {
        int result = i * j;
        System.out.println("方法內(nèi)部:resultMultiply = " + result);
        return result;
    }

    @Override
    public int div(int i, int j) {
        int result = i / j;
        System.out.println("方法內(nèi)部:resultDiv = " + result);
        return result;
    }
}
配置spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--開啟組件掃描-->
    <context:component-scan base-package="com.louis.annotation_aop"></context:component-scan>
<!--開啟aspectJ自動代理,為目標對象生成代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
創(chuàng)建切面類
切入點表達式

語法細節(jié)

用*號代替"權(quán)限修飾符"和"返回值部分"表示"權(quán)限修飾符"和"返回值"不限

包名的部分

①一個"*“號只能代表包的層次結(jié)構(gòu)中的一層,表示這一層是任意的。如:*.com匹配hello.com但不匹配hello.louis.com
②使用”*…"表示任意包名、包的層次深度任意

類名的部分

①類名整體使用*代替,表示類名任意
②可以使用*代替類名的一部分。如:*xxx表示匹配所有名稱以xxx結(jié)尾的類或接口

方法名的部分

①可以使用*代替,表示方法名任意
②可以使用*代替方法名的一部分。如:*xxx表示匹配所有名稱以xxx結(jié)尾的方法

方法參數(shù)列表部分

①可以使用(…)表示任意參數(shù)列表
②可以使用(int,…)表示參數(shù)列表以一個int類型的參數(shù)開頭
③基本數(shù)據(jù)類型和對應的包裝類型是不一樣的(切入點中使用int和實際方法中使用Integer是不匹配的)

方法返回值部分

如果想要明確指定一個返回值類型,那么必須同時寫明權(quán)限修飾符。如:excution(public int…Service.(…,int))

切面類(通知類型)
@Aspect
@Component //表示在spring的ioc容器中進行管理
public class LogAspect {
    //設置切入點和通知類型

    //通知類型:
    // 前置:@Before(value="通過切入點表達式配置切入點")
    //切入點表達式:execution(訪問修飾符 增強方法返回類型 方法所在類的全路徑.方法名(參數(shù)列表))
//    @Before("execution(* com.louis.annotation_aop.impl.LogAspect.*(..))")
    @Before("execution(public int com.louis.annotation_aop.impl.CalculatorImpl.*(..))")
    public void beforeMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("前置通知,增強的方法名稱" + name + " , 參數(shù)" + Arrays.toString(args));
    }
    // 返回:@AfterReturning,返回通知與后置通知有很大的區(qū)別,后置通知在返回通知之后執(zhí)行,返回通知能夠得到目標方法的返回值,使用屬性returning
    //它的參數(shù)可以隨便命名,但是切面方法的參數(shù)必須和上面的一致
    @AfterReturning(value = "execution(* com.louis.annotation_aop.impl.CalculatorImpl.*(..))", returning = "result")
    public void afterReturningMethod(JoinPoint joinPoint, Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("返回通知, 增強方法名稱" + name + " , 返回結(jié)果" + result);
    }
    // 異常:@AfterThrowing:目標方法出現(xiàn)異常,這個通知會執(zhí)行,并且能夠獲得目標方法的異常信息
    @AfterThrowing(value = "execution(* com.louis.annotation_aop.impl.CalculatorImpl.*(..))", throwing = "Exception")
    public void afterThrowingMethod(JoinPoint joinPoint, Throwable Exception){
        String name = joinPoint.getSignature().getName();
        System.out.println("異常通知, 增強方法名稱" + name + " , 返回結(jié)果" + Exception);
    }

    // 后置:@After()
    @After("execution(public int com.louis.annotation_aop.impl.CalculatorImpl.*(..))")
    public void afterMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("后置通知, 增強方法名稱" + name);
    }
    // 環(huán)繞:@Around()
    @Around("execution(public int com.louis.annotation_aop.impl.CalculatorImpl.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String argsString = Arrays.toString(args);
        Object result = null;
        try {
            System.out.println("環(huán)繞通知, 目標方法之前執(zhí)行");
            //調(diào)用目標方法
             result = joinPoint.proceed();

            System.out.println("環(huán)繞通知, 目標方法返回值之后執(zhí)行");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("環(huán)繞通知, 目標方法出現(xiàn)異常執(zhí)行");
        } finally {
            System.out.println("環(huán)繞通知, 目標方法執(zhí)行完畢");
        }
        return result;
    }
}
測試
@Test
public void testAOPAdd(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    Calculator calculator = context.getBean(Calculator.class);
    calculator.add(1,0);
}

/*
環(huán)繞通知, 目標方法之前執(zhí)行
前置通知,增強的方法名稱add , 參數(shù)[1, 0]
方法內(nèi)部:resultAdd = 1
返回通知, 增強方法名稱add , 返回結(jié)果1
后置通知, 增強方法名稱add
環(huán)繞通知, 目標方法返回值之后執(zhí)行
環(huán)繞通知, 目標方法執(zhí)行完畢
* */

@Test
public void testDiv(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    Calculator calculator = context.getBean(Calculator.class);
    calculator.div(1,0);
}

/*
環(huán)繞通知, 目標方法之前執(zhí)行
前置通知,增強的方法名稱div , 參數(shù)[1, 0]
異常通知, 增強方法名稱div , 返回結(jié)果java.lang.ArithmeticException: / by zero
后置通知, 增強方法名稱div
環(huán)繞通知, 目標方法出現(xiàn)異常執(zhí)行
環(huán)繞通知, 目標方法執(zhí)行完畢
* */

基于注解的AOP

重用切入點和切面優(yōu)先級
重用切入點
//重用切入點表達式,定義一個方法,之后在需要切入點的時候直接調(diào)用這個方法
/*
* 在同一個類下,可以直接使用:@Before("pointcut()")
* 在不同的類中,需要加入類的路徑:  @Before("com.louis.annotation_aop.impl.LogAspect.pointcut()")
* */
@Pointcut(value = "execution(public int com.louis.annotation_aop.impl.CalculatorImpl.*(..))")
public void pointcut(){

}
切面優(yōu)先級

相同目標方法上同時存在多個切面時,切面的優(yōu)先級控制切面的內(nèi)外嵌套順序
優(yōu)先級高的切面在外面,優(yōu)先級低的切面在里面。
使用@Order注解可以控制切面的優(yōu)先級
@Order(較小的數(shù)):優(yōu)先級高
@Order(較大的數(shù)):優(yōu)先級低

Spring-AOP(面向切面),Spring,spring,java,后端文章來源地址http://www.zghlxwxcb.cn/news/detail-602769.html

切面類
@Component //表示在spring的ioc容器中進行管理
public class LogAspect {
    //前置通知
    public void beforeMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        System.out.println("前置通知,增強的方法名稱" + name + " , 參數(shù)" + Arrays.toString(args));
    }
    // 返回通知
    public void afterReturningMethod(JoinPoint joinPoint, Object result){
        String name = joinPoint.getSignature().getName();
        System.out.println("返回通知, 增強方法名稱" + name + " , 返回結(jié)果" + result);
    }
    // 異常通知
    public void afterThrowingMethod(JoinPoint joinPoint, Throwable Exception){
        String name = joinPoint.getSignature().getName();
        System.out.println("異常通知, 增強方法名稱" + name + " , 返回結(jié)果" + Exception);
    }

    // 后置通知
    public void afterMethod(JoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        System.out.println("后置通知, 增強方法名稱" + name);
    }
    // 環(huán)繞通知
    public Object aroundMethod(ProceedingJoinPoint joinPoint){
        String name = joinPoint.getSignature().getName();
        Object[] args = joinPoint.getArgs();
        String argsString = Arrays.toString(args);
        Object result = null;
        try {
            System.out.println("環(huán)繞通知, 目標方法之前執(zhí)行");
            //調(diào)用目標方法
             result = joinPoint.proceed();

            System.out.println("環(huán)繞通知, 目標方法返回值之后執(zhí)行");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("環(huán)繞通知, 目標方法出現(xiàn)異常執(zhí)行");
        } finally {
            System.out.println("環(huán)繞通知, 目標方法執(zhí)行完畢");
        }
        return result;
    }


    //重用切入點表達式,定義一個方法,之后在需要切入點的時候直接調(diào)用這個方法
    /*
    * 在同一個類下,可以直接使用:@Before("pointcut()")
    * 在不同的類中,需要加入類的路徑:  @Before("com.louis.annotation_aop.impl.LogAspect.pointcut()")
    * */
    @Pointcut(value = "execution(public int com.louis.xml_aop.impl.CalculatorImpl.*(..))")
    public void pointcut(){

    }
}
配置文件beanaop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--開啟組件掃描-->
    <context:component-scan base-package="com.louis.xml_aop"></context:component-scan>
    <!--配置aop五種通知類型-->
    <aop:config>
        <!--配置切面類-->
        <aop:aspect ref="logAspect">
            <!--配置切入點-->
            <aop:pointcut id="pointcut" expression="execution(* com.louis.xml_aop.impl.CalculatorImpl.*(..))"/>
            <!--配置五種通知類型-->
            <!--前置通知-->
            <aop:before method="beforeMethod" pointcut-ref="pointcut"></aop:before>
            <!--后置通知-->
            <aop:after method="afterMethod" pointcut-ref="pointcut"></aop:after>
            <!--返回通知-->
            <aop:after-returning method="afterReturningMethod" returning="result" pointcut-ref="pointcut"></aop:after-returning>
            <!--異常通知-->
            <aop:after-throwing method="afterThrowingMethod" throwing="Exception" pointcut-ref="pointcut"></aop:after-throwing>
            <!--環(huán)繞通知-->
            <aop:around method="aroundMethod" pointcut-ref="pointcut"></aop:around>
        </aop:aspect>
    </aop:config>
</beans>
測試
@Test
public void testAOPXMLAdd(){
    ApplicationContext context = new ClassPathXmlApplicationContext("beanaop.xml");
    Calculator calculator = context.getBean(Calculator.class);
    calculator.add(1,0);
}
/*
前置通知,增強的方法名稱add , 參數(shù)[1, 0]
環(huán)繞通知, 目標方法之前執(zhí)行
方法內(nèi)部:resultAdd = 1
環(huán)繞通知, 目標方法返回值之后執(zhí)行
環(huán)繞通知, 目標方法執(zhí)行完畢
返回通知, 增強方法名稱add , 返回結(jié)果1
后置通知, 增強方法名稱add
* */

到了這里,關(guān)于Spring-AOP(面向切面)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關(guān)文章

  • Spring AOP:面向切面編程

    在軟件開發(fā)中,我們經(jīng)常會遇到一些橫切關(guān)注點(cross-cutting concerns),如日志記錄、事務管理和安全性等。這些關(guān)注點不屬于特定的模塊或類,而是橫跨整個應用程序。傳統(tǒng)的面向?qū)ο缶幊谭椒ㄍ鶗⑦@些關(guān)注點與核心業(yè)務邏輯混雜在一起,導致代碼的可讀性和可維護性下

    2024年02月09日
    瀏覽(22)
  • Spring面向切面編程(AOP)

    Spring面向切面編程(AOP)

    AOP(Aspect Oriented Programming),即面向切面編程,利用一種稱為\\\"橫切\(zhòng)\\"的技術(shù),剖開封裝的對象內(nèi)部,并將那些影響了多個類的公共行為封裝到一個可重用模塊,并將其命名為\\\"Aspect\\\",即切面。所謂\\\"切面\\\",簡單說就是那些與業(yè)務無關(guān),卻為業(yè)務模塊所共同調(diào)用的邏輯或責任封裝

    2024年02月07日
    瀏覽(31)
  • spring之面向切面:AOP(2)

    spring之面向切面:AOP(2)

    學習的最大理由是想擺脫平庸,早一天就多一份人生的精彩;遲一天就多一天平庸的困擾。各位小伙伴,如果您: 想系統(tǒng)/深入學習某技術(shù)知識點… 一個人摸索學習很難堅持,想組團高效學習… 想寫博客但無從下手,急需寫作干貨注入能量… 熱愛寫作,愿意讓自己成為更好

    2024年02月04日
    瀏覽(12)
  • [SSM]Spring面向切面編程AOP

    [SSM]Spring面向切面編程AOP

    目錄 十五、面向切面編程AOP 15.1AOP介紹 15.2AOP的七大術(shù)語 15.3切點表達式 15.4使用Spring的AOP 15.4.1準備工作 15.4.2基于AspectJ的AOP注解式開發(fā) 15.4.3基于XML配置方式的AOP(了解) 15.5AOP的實際案例:事務處理 15.6AOP的實際案例:安全日志 IoC使軟件組件松耦合。AOP讓你能夠捕捉系統(tǒng)中經(jīng)

    2024年02月15日
    瀏覽(28)
  • Spring AOP(面向切面編程)和方法攔截

    Spring AOP(面向切面編程)和方法攔截 Spring是一款廣泛使用的Java開發(fā)框架,提供了豐富的功能和工具,用于簡化企業(yè)級應用程序的開發(fā)。其中一個重要的特性是面向切面編程(AOP)和方法攔截。本文將介紹Spring AOP和方法攔截的概念、工作原理以及在實際開發(fā)中的應用。 在軟

    2024年02月05日
    瀏覽(23)
  • 認識 spring AOP (面向切面編程) - springboot

    認識 spring AOP (面向切面編程) - springboot

    本篇介紹什么是spring AOP, AOP的優(yōu)點,使用場景,spring AOP的組成,簡單實現(xiàn)AOP 并 了解它的通知;如有錯誤,請在評論區(qū)指正,讓我們一起交流,共同進步! 本文開始 AOP: 面向切面編程,也就是面向某一類編程,對某一類事情進行統(tǒng)一處理; spring AOP: 是實現(xiàn)了AOP這種思想的一

    2024年02月14日
    瀏覽(29)
  • 切面的魔力:解密Spring AOP 面向切面編程

    切面的魔力:解密Spring AOP 面向切面編程

    目錄 一、AOP簡介 1.1 什么是AOP ? 1.2?什么是面向切面編程 ? 1.3?AOP 的特點 二、?AOP的基本概念解讀 2.1 AOP的基本概念 2.2 AOP 概念趣事解讀 三、代碼情景演示 3.1?編寫目標對象(超級英雄們正常的行動) 3.2 編寫通知類 3.2.1?前置通知 3.2.2 后置通知 3.2.3 異常通知 3.2.4 環(huán)繞通知

    2024年02月11日
    瀏覽(89)
  • Spring系列篇--關(guān)于AOP【面向切面】的詳解

    Spring系列篇--關(guān)于AOP【面向切面】的詳解

    目錄 一.AOP是什么 二.案例演示? 1.前置通知1.1 先準備接口 1.2然后再準備好實現(xiàn)類 1.3對我們的目標對象進行JavaBean配置? 1.4 編寫前置系統(tǒng)日志通知 1.5配置系統(tǒng)通知XML中的JavaBean 1.6 配置代理XML中的JavaBean 1.7 測試代碼開始測試 注意這里有一個報錯問題?。?! 2. 后置通知2.1 先準

    2024年02月12日
    瀏覽(20)
  • spring6-AOP面向切面編程

    spring6-AOP面向切面編程

    1、場景模擬 搭建子模塊:spring6-aop 1.1、聲明接口 聲明計算器接口Calculator,包含加減乘除的抽象方法 1.2、創(chuàng)建實現(xiàn)類 1.3、創(chuàng)建帶日志功能的實現(xiàn)類 1.4、提出問題 ①現(xiàn)有代碼缺陷 針對帶日志功能的實現(xiàn)類,我們發(fā)現(xiàn)有如下缺陷: 對核心業(yè)務功能有干擾,導致程序員在開發(fā)核

    2024年02月08日
    瀏覽(31)
  • 【Spring AOP】結(jié)合日志面向切面編程 兩種寫法

    ??????? 這里需要提前了解什么是Spring的AOP(Aspect Oriented Programming)。是在OOP(面向?qū)ο螅┧枷氲囊环N拓展思想。 簡單來說就是將某個代碼塊嵌入到其它的代碼塊中 。筆者先前學Spring也有學什么IoC啊AOP啊,但實際上沒有用過、就那聽過學過沒啥用的。。沒會兒就忘記了。

    2024年02月13日
    瀏覽(28)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包