1. 程式人生 > >Spring原始碼解析(十一)——AOP原理——demo

Spring原始碼解析(十一)——AOP原理——demo

1.業務類

public class MathCalculator {
    public int div(int i, int j) {
        System.out.println("MathCalculator---div");
        return i / j;
    }
}

2.切面類

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

@Aspect
public class LogAspects {

    @Pointcut("execution(public int com.atguigu.gmall.aop.MathCalculator.div(int, int))")
    public void pointCut() {

    }

    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint) {
        Object[] args = joinPoint.getArgs();
        System.out.println("" + joinPoint.getSignature().getName() + "執行。。。引數列表是:{" + Arrays.asList(args) + "}");
    }

    @After("pointCut()")
    public void logEnd(JoinPoint joinPoint) {
        System.out.println("" + joinPoint.getSignature().getName() + "結束。。。");
    }

    @AfterReturning(value = "pointCut()", returning = "result")
    public void logReturn(JoinPoint joinPoint, Object result) {
        System.out.println("" + joinPoint.getSignature().getName() + "正常返回。。。執行結果:{" + result + "}");
    }

    //JoinPoint一定要出現在引數列表的第一位
    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void logException(JoinPoint joinPoint, Exception exception) {
        System.out.println("" + joinPoint.getSignature().getName() + "異常。。。異常資訊:{" + exception + "}");
    }
}

3.配置類

import com.atguigu.gmall.aop.LogAspects;
import com.atguigu.gmall.aop.MathCalculator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
 * 1.定義一個業務邏輯類(MathCalculator)
 * 2.定義一個日誌切面類(LogAspects):切面類裡面的方法需要動態感知MathCalculator.div執行到
 * 通知方法:
 * 返回通知(@AfterReturning):logReturn:在目標方法div正常返回之後執行
 * 異常通知(@AfterThrowing):logException:在目標方法div出現異常之後執行
 * 環繞通知(@Around):動態代理,手動推進目標方法執行(joinPoint.procced())
 * 3.給切面類的目標方法標註何時何地執行(通知註解)
 * 4.將切面類和業務邏輯類(目標方法所在類)都加入到容器中
 * 5.告訴spring哪個類是切面類(給切面類加註解:@Aspect)
 * 6.給配置類加@EnableAspectJAutoProxy(開啟基於註解的aop模式)
 *
 * @EnableXXX,開啟XXX功能
 *
 * 三步:
 * 1)將業務邏輯元件和切面類都加入到容器中;告訴spring哪個是切面類(@Aspect)
 * 2)在切面類上的每一個通知方法上標註通知註解,告訴spring何時何地執行(切入點表示式)
 * 3)開啟基於註解的aop模式;@EnableAspectJAutoProxy
 *
 *
 */
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {

    @Bean
    public MathCalculator calculator() {
        return new MathCalculator();
    }

    @Bean
    public LogAspects logAspects() {
        return new LogAspects();
    }
}

4.測試類

public class AopTest {

    @Test
    public void run1() {
        ApplicationContext ac = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
        MathCalculator bean = ac.getBean(MathCalculator.class);
//        bean.div(2, 1);
        bean.div(2, 0);
    }
}