前言
說句實話,在工作中,使用的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);
}
好的,看下結果吧。
總結
即將開啓源碼模式。