更新時(shí)間:2022-08-09 10:52:27 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽786次
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ù)邏輯類(lèi)(CalculateController);在業(yè)務(wù)邏輯運(yùn)行的時(shí)候?qū)⑷罩具M(jìn)行打印(方法之前、方法運(yùn)行結(jié)束、方法出現(xiàn)異常,xxx)
3.定義一個(gè)日志切面類(lèi)(LogAop):切面類(lèi)里面的方法需要?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)行(無(wú)論方法正常結(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.給切面類(lèi)的目標(biāo)方法標(biāo)注何時(shí)何地運(yùn)行(通知注解);
5.將切面類(lèi)和業(yè)務(wù)邏輯類(lèi)(目標(biāo)方法所在類(lèi))都加入到容器中;
6.必須告訴Spring哪個(gè)類(lèi)是切面類(lèi)(給切面類(lèi)上加一個(gè)注解:@Aspect)
7.給配置類(lèi)中加 @EnableAspectJAutoProxy 【開(kāi)啟基于注解的aop模式】
在Spring中很多的 @EnableXXX;
三步:
1)將業(yè)務(wù)邏輯組件和切面類(lèi)都加入到容器中;告訴Spring哪個(gè)是切面類(lèi)(@Aspect)
2)在切面類(lèi)上的每一個(gè)通知方法上標(biāo)注通知注解,告訴Spring何時(shí)何地運(yùn)行(切入點(diǎn)表達(dá)式)
3)開(kāi)啟基于注解的aop模式;@EnableAspectJAutoProxy
// @EnableAspectJAutoProxy 開(kāi)啟基于注解的aop模式
@EnableAspectJAutoProxy
@Configuration
public class MyAopConfig {
@Bean
public CalculateController calculateController(){
return new CalculateController();
}
@Bean
public LogAop logAop(){
return new LogAop();
}
}
/**
* 切面類(lèi)
*/
// @Aspect: 告訴Spring當(dāng)前類(lèi)是一個(gè)切面類(lèi)
@Aspect
public class LogAop {
//抽取公共的切入點(diǎn)表達(dá)式
//1、本類(lèi)引用
//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())+"}");
}
// 外部切面類(lèi)引用可以用全類(lèi)名
@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類(lèi)的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)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)
初級(jí) 202925
初級(jí) 203221
初級(jí) 202629
初級(jí) 203743