javascript
Spring Boot 集成AOP
在這里多談一些關于AOP 方面的知識,如果你對AOP 方面的知識比較熟悉,可以直接略過這個段落,往下看。
一、AOP概述
AOP(面向切面編程) 概念:這種在運行時,動態地將代碼切入到類的指定方法、指定位置上的編程思想就是面向切面的編程。
AOP 相關術語:
- Aspect(切面):指橫切性的關注點的抽象即為切面,它與類相似,只是兩者的關注點不一樣,類是對物體特征的抽象,而切面是對橫切性關注點的抽象。是Pointcut和Advice的結合,切面可以由多個Poincut和Advice組成。
- Joinpoint(連接點):被攔截的點(也就是需要被攔截的類的方法)。在spring中,這些點指的只能是方法,因為Spring只支持方法類型的攔截,實際上Joinpoint還可以攔截field或類構造器。
- Pointcut(切點):對Jointpoint(連接點)進行攔截的定義,也就是在切面中定義的方法,并聲明該方法攔截了Jointpoint(連接點)。
- Advice(通知):切入點攔截到Jointpoint(連接點)之后要做的事情。通知分為前置通知(@Before)、后置通知(@AfterReturning)、異常通知(@AfterThrowing)、最終通知(@After)和環繞通知(@Around)。
- Target(目標對象):代理的目標對象。
- Weave(織入):指將aspects應用到target對象并使proxy對象創建的過程稱為織入。
五種基本通知類型注解:
- 前置通知(@Before):攔截目標方法,在目標方法執行之前開始執行。
- 后置通知(After):在目標方法執行之后開始執行。也可以獲取目標方法的返回值。
- 返回通知(@AferRunning):在方法返回執行結果之后執行。
- 異常通知(@AfterThrowing):在目標方法拋出異常后,執行增強。
- 環繞通知(@Around):相當于整個代理模式過程,圍繞方法執行。
二、在Spring Boot 中使用AOP
開發流程:
過程實現:
在pom.xml 中添加AOP 依賴
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>Person 類
package com.jas.aop;import org.springframework.stereotype.Component;@Component public class Person {public void sayHi(){System.out.println("Hello");} }Log 類
package com.jas.aop;import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;/** 使用@Component 把這個類納入到Spring 容器,@Aspect 注解表示這個類是一個切面類 */ @Component @Aspect public class Log {/** 定義一個前置通知*//** 匹配com.jas.aop 包及其子包下的所有方法 */@Before("execution(* com.jas.aop..*.*(..))")public void log(){System.out.println("... before ...");} }測試類(入口類)
package com.jas.springboot;import com.jas.aop.Person; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication(scanBasePackages = "com.jas") public class SpringbootApplication {public static void main(String[] args) throws Exception{ConfigurableApplicationContext context = SpringApplication.run(SpringbootApplication.class, args);Person person = context.getBean(Person.class);person.sayHi();System.out.println(person.getClass());} }啟動入口類輸出
三、Spring Boot AOP 兩種動態代理方式
動態代理方式概述:
AOP 的源碼中用到了兩種動態代理來實現攔截切入功能:JDK 動態代理和CGLIB 動態代理。兩種方式各有優劣。
JDK 動態代理是由java 內部的反射機制來實現的,CGLIB 動態代理底層則是借助asm 來實現的??偟膩碚f,反射機制在生成類的過程中比較高效,而asm 在生成類之后的相關執行過程中比較高效(可以通過將asm 生成的類進行緩存,這樣解決asm 生成類過程低效問題)。
還有一點必須注意:JDK 動態代理的應用前提,必須是目標類基于統一的接口。如果沒有上述前提,JDK 動態代理不能應用。由此可以看出,JDK 動態代理有一定的局限性,CGLIB 這種第三方類庫實現的動態代理應用更加廣泛,且在效率上更有優勢。。
關于JDK 動態代理知識,可參考博文:JDK 動態代理。
但是從上面的輸出來看使用的是基于CGLIB 的代理方式,因為JDK 的動態代理類必須是實現了接口的類。下面寫一個接口類來測試一下。
動態代理方式演示:
在全局配置文件中配置代理方式,true 表示使用CGLIG,false 表示使用JDK 動態代理。
需要注意的是,當為false 時,如果代理類沒有實現接口,則使用的也是基于CGLIB 的動態代理。
Animal 接口
package com.jas.aop;public interface Animal {void yell(); }Dog 類
package com.jas.aop;import org.springframework.stereotype.Component;@Component public class Dog implements Animal{@Overridepublic void yell() {System.out.println("wang wang ...");} }在入口類加上對應的代碼
System.out.println(context.getBean(Animal.class).getClass());輸出
參考資料
http://blog.csdn.net/heyutao007/article/details/49738887
總結
以上是生活随笔為你收集整理的Spring Boot 集成AOP的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何下载支付宝到手机上
- 下一篇: Spring Boot 集成测试