面向切面編程AOP[一](java 代碼詳解)

前言

說句實話,在工作中,使用的aop不是特別多,但是特別重要,一般是輔助程序,在現代開發者輔助程序相當重要,比如說我們需要打印一些log,但是我們不可能去卸載我們的業務程序中,因爲這太。。。。。

正文

那麼如何開啓一個aop呢?用log舉例,我們不可能去寫log在我們的業務程序中,如果是這樣的話,是真的難以維護。

下面實例一個需求來顯示出一些問題:

/**
 *需求
 * 將一個方法的發生前打印出log,發生後打印log,異常打印log,要求解耦
 * 通知:
 *     前置通知(@Befor)
 *     後置通知 (@After)
 *     返回通知 (@AfterReturning)
 *     異常通知 (@AfterThrowing)
 *     環繞通知(@Around):動態代理,手動推進目標方法運行(joinpoint.procced)
 * 步驟:
 *    1.將業務邏輯組件和切面類都加入到容器中,告訴spring 哪個是切面類,開啓基於註解的aop模式@EnableAspectJAutoProxy
 *    2.在切面類上的每一個通知方法上標註通知註解,告訴spring 何時何地運行(切入點表達式)

首先加入容器中:

@Configuration
@EnableAspectJAutoProxy
public class MainConfigofAOP {

    //業務邏輯類加入到容器中
    @Bean
    public MathCalculator calculator(){
        return  new MathCalculator();
    }

    //切面類加入到容器中
    @Bean
    public LogAspects logAspects(){
        return  new LogAspects();
    }
}

將切面類和業務邏輯類加入到容器中,然後開啓切面@EnableAspectJAutoProxy。

接下來我們看下如何告訴切面註解實現類,哪個是切面,看下切面類:

/**
 * 切面類
 */
@Aspect
public class LogAspects {

    //公共的切入點表達式
    @Pointcut("execution(public int com.axm.demo.aop.MathCalculator.*(..))")
    public  void pointCut(){

    }
//    @Before("public  int com.axm.demo.aop.div(int i,int j)")
    @Before("pointCut()")
    public  void logStart(JoinPoint joinPoint)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法運行前執行,參數是:"+Arrays.asList(joinPoint.getArgs()));
    }

    @After("pointCut())")
    public  void  logEnd(JoinPoint joinPoint)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法運行後執行,無論是否異常都會執行");
    }

    @AfterReturning(value="pointCut()",returning = "result")
    public  void resultReturn(JoinPoint joinPoint,Object result)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法成功後執行!獲取返回結果:"+result);
    }
    @AfterThrowing(value = "pointCut()",throwing = "exception")
    public  void logException(JoinPoint joinPoint,Exception exception)
    {
        System.out.println(""+joinPoint.getSignature().getName()+"方法成功後執行!查看異常:"+exception.getMessage());
    }
}

註解:@Aspect 告訴應用該類爲切面類。

@Pointcut("execution(public int com.axm.demo.aop.MathCalculator.*(..))")

是公共表達式,@Before("pointCut()")表示繼承pointCut方法的註解。

public int com.axm.demo.aop.MathCalculator.*(..) 表示在MathCalculator 中的所以方法將會被監聽。

JoinPoint joinPoint 表示目標方法的一些信息。

這些都可以去文檔中查看。

再看下業務邏輯類:

public class MathCalculator {

    public  int div(int i,int j){
        return  i/j;
    }
}

業務邏輯類,就像是正常一樣去書寫即可,只要加入容器中。

也就是說我們在不影響現在代碼的情況下,可以去實現一些輔助功能。

這裏,測試一下。

@Test
public  void  test()
{
	AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigofAOP.class);
	MathCalculator mathCalculator=applicationContext.getBean(MathCalculator.class);
	mathCalculator.div(1,1);
}

好的,看下結果吧。

總結

即將開啓源碼模式。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章