1. 程式人生 > 實用技巧 >五、AOP入門

五、AOP入門

AOP:【動態代理】

指在程式執行期間動態的將某段程式碼切入到指定方法指定位置進行執行的程式設計方式;

一、匯入aop模組;Spring AOP:(spring-aspects)

     <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>4.3.12.RELEASE</version>
        </
dependency>

二、定義一個業務邏輯類(MathCalculator)

在業務邏輯執行的時候將日誌進行列印(方法之前、方法執行結束、方法出現異常,xxx)

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

三、定義一個日誌切面類(LogAspects):

  切面類裡面的方法需要動態感知MathCalculator.div執行到哪裡然後執行;

  通知方法:

    • 前置通知(@Before):logStart:在目標方法(div)執行之前執行
    • 後置通知(@After):logEnd:在目標方法(div)執行結束之後執行(無論方法正常結束還是異常結束)
    • 返回通知(@AfterReturning):logReturn:在目標方法(div)正常返回之後執行
    • 異常通知(@AfterThrowing):logException:在目標方法(div)出現異常以後執行
    • 環繞通知(@Around):動態代理,手動推進目標方法執行(joinPoint.procced())’
  • 給切面類的目標方法(div方法)標註何時何地執行(通知註解);
  • 將切面類和業務邏輯類(目標方法所在類)都加入到容器中;
  • 必須告訴Spring哪個類是切面類(給切面類上加一個註解:@Aspect)
  • 給配置類中加 @EnableAspectJAutoProxy 【開啟基於註解的aop模式】
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
@Aspect
public class LogAspects {
    
    //抽取公共的切入點表示式
    //1、本類引用
    //2、其他的切面引用
    @Pointcut("execution(public int com.atguigu.aop.MathCalculator.*(..))")
    public void pointCut(){};
    
    //@Before在目標方法之前切入;切入點表示式(指定在哪個方法切入)
    @Before("pointCut()")
    public void logStart(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println(""+joinPoint.getSignature().getName()+"執行。。。@Before:引數列表是:{"+Arrays.asList(args)+"}");
    }
    
    @After("com.atguigu.aop.LogAspects.pointCut()")
    public void logEnd(JoinPoint joinPoint){
        System.out.println(""+joinPoint.getSignature().getName()+"結束。。。@After");
    }
    
    //JoinPoint一定要出現在引數表的第一位
    @AfterReturning(value="pointCut()",returning="result")
    public void logReturn(JoinPoint joinPoint,Object result){
        System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:執行結果:{"+result+"}");
    }
    
    @AfterThrowing(value="pointCut()",throwing="exception")
    public void logException(JoinPoint joinPoint,Exception exception){
        System.out.println(""+joinPoint.getSignature().getName()+"異常。。。異常資訊:{"+exception+"}");
    }

測試

@Test
    public void test01(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
        
        //1、不要自己建立物件
//        MathCalculator mathCalculator = new MathCalculator();
//        mathCalculator.div(1, 1);
        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
        
        mathCalculator.div(1, 0);
        
        applicationContext.close();
    }

AOP的使用步驟:三步:

  • 將業務邏輯元件和切面類都加入到容器中;告訴Spring哪個是切面類(@Aspect)

  • 在切面類上的每一個通知方法上標註通知註解,告訴Spring何時何地執行(切入點表示式)

  • 開啟基於註解的aop模式;@EnableAspectJAutoProxy