一、什麼是AOP:
AOP又稱動態代理,指在程序運行期間動態的將某段代碼切入到指定方法指定位置進行運行的編程模式
二、AOP示例代碼
第一步、導入AOP相應的依賴
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.2.2.RELEASE</version>
</dependency>
第二步、創建業務邏輯類
public class BookService {
public int save(String name)
{
System.out.println("業務存儲邏輯");
return 1;
}
}
第三步、創建切面類
定義一個日誌切面類(LogAspect),切面類裏面的方法需要動態感知BookService的方法運行到哪裏,然後執行通知方法: 前置通知(@Before):logStart:在目標方法運行之前運行 參數列表傳入joinPoint可獲取到方法的相關屬性, 且該參數必須放在第一個參數,否則無法識別 後置通知(@After):logEnd:在目標方法運行之後運行,無論方法正常結束還是異常結束 返回通知(@AfterReturning(returning可以指定封裝返回值的參數)) 異常通知(@AfterThrowing(logException可以獲取異常信息)) 環繞通知(@Around):動態代理,手動推進目標方法運行(joinPoint.proceed())
/**
* 切面類
*/
@Aspect
public class LogAspect {
//抽取公共的切入點表達式
//1、本類引用
@Pointcut("execution(public int com.example.demo.service.BookService.*(..))")
public void pointCut(){}
//在目標方法之前切入:切入點表達式(指定在哪個方法切入)
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
System.out.println("aop切面before:"+
joinPoint.getSignature().getName()+
"方法運行。。。參數列表是:{"+ Arrays.asList(joinPoint.getArgs())+"}");
}
//在目標方法之後切入
@After("pointCut()")
public void logEnd(){
System.out.println("aop切面,after");
}
@AfterReturning(value = "pointCut()",returning ="result" )
public void logReturn(Object result){
System.out.println("除法正常返回。。運行結果:{"+result+"}");
}
@AfterThrowing(value = "pointCut()",throwing ="exception")
public void LogException(Exception exception){
System.out.println("除法異常。。異常信息:{"+exception+"}");
}
}
四、創建配置類
我們將上面的切面類和業務邏輯類註冊到spring容器中,讓spring進行管理
需要給配置類加一個@EnableAspectJAutoProxy【開啓基於註解的aop模式】
//需要給配置類加一個@EnableAspectJAutoProxy【開啓基於註解的aop模式】
@EnableAspectJAutoProxy
@Configuration
public class MainConfig {
//業務邏輯類加入容器中
@Bean
public BookService bookService()
{
return new BookService();
}
//切面類加入容器中
@Bean
public LogAspect logAspect(){
return new LogAspect();
}
}
五、編寫測試類
@SpringBootTest
class DemoApplicationTests {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
@Test
void contextLoads() {
BookService bookService = applicationContext.getBean(BookService.class);
bookService.save("小明");
}
}
測試結果
aop切面before:save方法運行。。。參數列表是:{[小明]}
業務存儲邏輯
aop切面,after
除法正常返回。。運行結果:{1}
有方法有異常,則結果如下
aop切面before:save方法運行。。。參數列表是:{[小明]}
業務存儲邏輯
aop切面,after
除法異常。。異常信息:{java.lang.ArithmeticException: / by zero}
總結:
AOP功能分三步:
1、創建切面類、並告訴spring哪個是切面類(@Aspect)
2、在切面類上的每一個通知方法標註通知註解,告訴spring何時何地運行(切入點表達式)
3、將業務邏輯組件和切面類都加入到容器中,開啓基於註解的aop模式@EnableAspectJAutoProxy