更新時(shí)間:2022-08-09 10:52:27 來源:動(dòng)力節(jié)點(diǎn) 瀏覽899次
AOP配置,@EnableAspectJAutoProxy,@Before,@After,@AfterReturning,@AfterThrowing
指在程序運(yùn)行期間動(dòng)態(tài)的將某段代碼切入到指定方法指定位置進(jìn)行運(yùn)行的編程方式;
1.導(dǎo)入aop模塊;Spring AOP:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2.定義一個(gè)業(yè)務(wù)邏輯類(CalculateController);在業(yè)務(wù)邏輯運(yùn)行的時(shí)候?qū)⑷罩具M(jìn)行打印(方法之前、方法運(yùn)行結(jié)束、方法出現(xiàn)異常,xxx)
3.定義一個(gè)日志切面類(LogAop):切面類里面的方法需要?jiǎng)討B(tài)感知CalculateController.calculateNum運(yùn)行到哪里然后執(zhí)行;
通知方法:
前置通知(@Before):logStart:在目標(biāo)方法(calculateNum)運(yùn)行之前運(yùn)行
后置通知(@After):logEnd:在目標(biāo)方法(calculateNum)運(yùn)行結(jié)束之后運(yùn)行(無論方法正常結(jié)束還是異常結(jié)束)
返回通知(@AfterReturning):logReturn:在目標(biāo)方法(calculateNum)正常返回之后運(yùn)行
異常通知(@AfterThrowing):logException:在目標(biāo)方法(calculateNum)出現(xiàn)異常以后運(yùn)行
環(huán)繞通知(@Around):動(dòng)態(tài)代理,手動(dòng)推進(jìn)目標(biāo)方法運(yùn)行(joinPoint.procced())
4.給切面類的目標(biāo)方法標(biāo)注何時(shí)何地運(yùn)行(通知注解);
5.將切面類和業(yè)務(wù)邏輯類(目標(biāo)方法所在類)都加入到容器中;
6.必須告訴Spring哪個(gè)類是切面類(給切面類上加一個(gè)注解:@Aspect)
7.給配置類中加 @EnableAspectJAutoProxy 【開啟基于注解的aop模式】
在Spring中很多的 @EnableXXX;
三步:
1)將業(yè)務(wù)邏輯組件和切面類都加入到容器中;告訴Spring哪個(gè)是切面類(@Aspect)
2)在切面類上的每一個(gè)通知方法上標(biāo)注通知注解,告訴Spring何時(shí)何地運(yùn)行(切入點(diǎn)表達(dá)式)
3)開啟基于注解的aop模式;@EnableAspectJAutoProxy
// @EnableAspectJAutoProxy 開啟基于注解的aop模式
@EnableAspectJAutoProxy
@Configuration
public class MyAopConfig {
@Bean
public CalculateController calculateController(){
return new CalculateController();
}
@Bean
public LogAop logAop(){
return new LogAop();
}
}
/**
* 切面類
*/
// @Aspect: 告訴Spring當(dāng)前類是一個(gè)切面類
@Aspect
public class LogAop {
//抽取公共的切入點(diǎn)表達(dá)式
//1、本類引用
//2、其他的切面引用
@Pointcut("execution(public int com.example.studywork.work.controller.CalculateController.*(..))")
public void pointCut(){};
@Before(value ="pointCut()")
public void logStart(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName()+"方法運(yùn)行前。。。參數(shù)列表是:{"+ Arrays.asList(joinPoint.getArgs())+"}");
}
// 外部切面類引用可以用全類名
@After("com.example.studywork.work.aop.LogAop.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(joinPoint.getSignature().getName()+"方法結(jié)束。。。");
}
//JoinPoint一定要出現(xiàn)在參數(shù)表的第一位
@AfterReturning(value = "pointCut()",returning = "obj")
public void logReturn(JoinPoint joinPoint,Object obj){
System.out.println(joinPoint.getSignature().getName()+"方法正常返回。。。運(yùn)行結(jié)果是:{"+obj+"}");
}
@AfterThrowing(value = "pointCut()",throwing = "e")
public void logxception(JoinPoint joinPoint,Exception e){
System.out.println(joinPoint.getSignature().getName()+"方法異常返回。。。異常結(jié)果是:{"+e+"}");
}
}
// 業(yè)務(wù)
public class CalculateController {
public int calculateNum(int i, int j){
System.out.println("CalculateController類的calculateNum方法正在運(yùn)行");
return i/j;
}
}
輸出
@Test
public void test() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyAopConfig.class);
CalculateController bean = applicationContext.getBean(CalculateController.class);
bean.calculateNum(1,1);
}
輸出結(jié)果
異常輸出
@Test
public void test() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyAopConfig.class);
CalculateController bean = applicationContext.getBean(CalculateController.class);
bean.calculateNum(1,0);
}
輸出結(jié)果
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)