一. AOP定義
AOP指在程序運行期間動態(tài)的將某段代碼切入到指定方法指定位置運行的編程方式。
二. AOP流程
導入aop模塊:Spring AOP(spring-aspects)
定義一個業(yè)務(wù)邏輯類(MathCalculator):在業(yè)務(wù)邏輯運行的時候?qū)⑷罩具M行打印(方法之前、方法運行結(jié)束、方法出現(xiàn)異常嘉冒、xxxx)
-
定義一個日志切面類(LogAspects):切面類里面的方法需要動態(tài)感知MathCalculator.div 運行到哪里然后執(zhí)行:
通知方法:- 前置通知(@Before):logStart:在目標方法(div)運行之前運行
- 后置通知(@After):logEnd:在目標方法(div)運行結(jié)束之后運行(無論方法正常結(jié)束還是異常結(jié)束)
- 返回通知(@AfterReturning):logReturn:在目標方法(div)正常返回之后運行
- 異常通知(@AfterThrowing):logException:在目標方法(div)出現(xiàn)異常以后運行。
- 環(huán)繞通知(@Around):動態(tài)代理,手動推進目標方法運行(joinPoint.procced())
給切面類的目標方法標注何時何地運行(通知注解)
將切面類和業(yè)務(wù)邏輯類(目標方法所在類)都加入到容器中亮垫;
6.必須告訴spring哪個類是切面類(給切面類加一個注解@Aspect)
7、給配置類中加 @EnableAspectJAutoProxy 【開啟基于注解的aop模式】在Spring中很多的@EnableXXX;
三步:
1)伟骨、將業(yè)務(wù)邏輯組件和切面類都加入到容器中饮潦;告訴spring哪個是切面類(@Aspect)
2)、在切面類上的每一個通知方法上標注通知注解携狭,告訴spring何時何地運行(切入點表達式)
3)继蜡、開啟基于注解的aop模式:@EnableAspectJAutoProxy
MainConfigOfAOP.java
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
//業(yè)務(wù)邏輯類加入容器中
@Bean
public MathCalculator calculator(){
return new MathCalculator();
}
//切面類加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
MathCalculator.java
public class MathCalculator {
public int div(int i,int j){
System.out.println("MathCalculator...div...");
return i/j;
}
}
LogAspects.java
/**
* 切面類
*
* @Aspect: 告訴Spring當前類是一個切面類
*
*/
@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:參數(shù)列表是:{"+Arrays.asList(args)+"}");
}
@After("com.atguigu.aop.LogAspects.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"結(jié)束。搁廓。引颈。@After");
}
//JoinPoint一定要出現(xiàn)在參數(shù)表的第一位
@AfterReturning(value="pointCut()",returning="result")
public void logReturn(JoinPoint joinPoint,Object result){
System.out.println(""+joinPoint.getSignature().getName()+"正常返回。枚抵。线欲。@AfterReturning:運行結(jié)果:{"+result+"}");
}
@AfterThrowing(value="pointCut()",throwing="exception")
public void logException(JoinPoint joinPoint,Exception exception){
System.out.println(""+joinPoint.getSignature().getName()+"異常。汽摹。李丰。異常信息:{"+exception+"}");
}
}