spring boot:AOP

1、簡(jiǎn)介

  • AOP即面向切面編程Aspect Oriented Program。
  • 面向切面編程將系統(tǒng)功能分為核心業(yè)務(wù)功能切面功能,核心業(yè)務(wù)功能主要是注冊(cè)登錄、數(shù)據(jù)庫(kù)操作等,切面功能主要有日志、權(quán)限、性能分析等。
  • AOP將與核心功能一起調(diào)用的任務(wù)和邏輯分離開(kāi)并封裝起來(lái),有助于減少系統(tǒng)的重復(fù)代碼,降低模塊間的耦合度。

2、AOP中的概念

  • 切點(diǎn)(PointCut):指定切入的類(lèi)或方法(\color{red}{where}
  • 通知(Advice):對(duì)方法在什么時(shí)間(\color{red}{when})需要執(zhí)行的操作(\color{red}{what}
  • 切面(Aspect):切點(diǎn)+通知
  • 織入(Weaving):將切面加入到對(duì)象中,并創(chuàng)建代理的過(guò)程。

3、AOP的通知類(lèi)型

  • before(前置通知):在方法開(kāi)始執(zhí)行前執(zhí)行
  • after(后置通知): 在方法執(zhí)行后執(zhí)行
  • afterReturning(返回后通知): 在方法返回后執(zhí)行
  • afterThrowing(異常通知): 在拋出異常時(shí)執(zhí)行
  • around(環(huán)繞通知): 在方法執(zhí)行前和執(zhí)行后都會(huì)執(zhí)行

4、快速入門(mén)

  • 構(gòu)建spring boot項(xiàng)目
  • 引入AOP依賴(lài)
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
  • 創(chuàng)建一個(gè)service類(lèi)
public class Calculator {

    public int divide(int a, int b) {
        System.out.println("除法:" + a + "/" + b);
        return a / b;
    }

    public int add(int a, int b) {
        System.out.println("加法:" + a + "+" + b);
        return a + b;
    }
}
  • 編寫(xiě)切面類(lèi)
@Aspect
public class CalculatorAop {

    //切點(diǎn) Calculator的+-*/方法
    @Pointcut("execution(public int com.samllbear.aopdemo.service.Calculator.divide(..))")
    public void pointCut() {}

    @Before("pointCut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("Before...");
        Signature signature = joinPoint.getSignature(); // 獲取方法的簽名
        System.out.println("執(zhí)行運(yùn)算:" + signature.getName()); // 獲取方法名稱(chēng)
        System.out.println("執(zhí)行參數(shù):" + Arrays.toString(joinPoint.getArgs())); // 方法參數(shù)
    }

    @After("pointCut()")
    public void after() {
        System.out.println("After...");
    }

    @AfterReturning(value = "pointCut()", returning = "result")
    public void afterReturning(Object result) {
        System.out.println("Returning...");
        System.out.println("執(zhí)行結(jié)果:" + result);
    }

    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void afterThrowing(Exception exception) {
        System.out.println("Throwing...");
        System.out.println(exception.getMessage());
    }
}
  • 編寫(xiě)配置類(lèi)
@Configuration
@EnableAspectJAutoProxy // 開(kāi)啟aop
public class CalculatorConfig {

    @Bean // 注入計(jì)算器
    public Calculator calculator() {
        return new Calculator();
    }

    @Bean // 注入aop
    public CalculatorAop calculatorAop() {
        return new CalculatorAop();
    }
}
  • 測(cè)試
class AopDemoApplicationTests {

    @Test
    public void divideTest() {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(CalculatorConfig.class);
        // 注意只有注入容器的bean AOP才會(huì)生效
        Calculator calculator = context.getBean(Calculator.class);
//        calculator.divide(13, 0);  // throwing... /By Zero
        calculator.divide(13, 2);
    }
}
Before...
執(zhí)行運(yùn)算:divide
執(zhí)行參數(shù):[13, 2]
除法:13/2
After...
Returning...
執(zhí)行結(jié)果:6
  • 環(huán)繞通知(Around)可以用來(lái)替換以上四種通知
    CalculatorAop.class添加以下代碼
    private static final Logger log = LoggerFactory.getLogger(CalculatorAop.class);

    @Pointcut("execution(public int com.samllbear.aopdemo.service.Calculator.add(..))")
    public void addPointCut() {}

    @Around("addPointCut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        try {
            System.out.println("around begin...");
            Object o = joinPoint.proceed(); // 執(zhí)行目標(biāo)方法
            System.out.println("around end...");
            return o;
        } catch (Throwable e) {
            System.out.println("around throwing...");
            log.error(e.getMessage());
            throw e;
        } finally {
            System.out.println("around returning...");
        }
    }
  • 測(cè)試
    @Test
    public void addTest() {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(CalculatorConfig.class);
        Calculator calculator = context.getBean(Calculator.class);
        calculator.add(13, 0);
    }
around begin...
加法:13+0
around end...
around returning...
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容