本篇文章主要介紹的是SpringBoot切面Aop的demo簡單講解。html
說明:若是想直接獲取工程那麼能夠直接跳到底部,經過連接下載工程代碼。java
1、概念git
AOP(Aspect OrientedProgramming):面向切面編程,面向切面編程(也叫面向方面編程),是目前軟件開發中的一個熱點,也是Spring框架中的一個重要內容。利用AOP能夠對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度下降,提升程序的可重用性,同時提升了開發的效率。github
2、用途web
日誌記錄,性能統計,安全控制,權限管理,事務處理,異常處理,資源池管理。spring
3、詳解編程
1.切面(Aspect):
官方的抽象定義爲「一個關注點的模塊化,這個關注點可能會橫切多個對象」,在本例中,「切面」就是類TestAspect所關注的具體行爲,例如:AServiceImpl.barA()的調用就是切面TestAspect所關注的行爲之一。「切面」在ApplicationContext中aop:aspect來配置。json
2.鏈接點(Joinpoint):
程序執行過程當中的某一行爲,例如,AServiceImpl.barA()的調用或者BServiceImpl.barB(String _msg, int _type)拋出異常等行爲。api
3.通知(Advice):
「切面」對於某個「鏈接點」所產生的動做,例如,TestAspect中對com.spring.service包下全部類的方法進行日誌記錄的動做就是一個Advice。其中,一個「切面」能夠包含多個「Advice」,例如TestAspect。Advice共有以下5種類型:瀏覽器
4.切入點(Pointcut)
匹配鏈接點的斷言,在AOP中通知和一個切入點表達式關聯。例如,TestAspect中的全部通知所關注的鏈接點,都由切入點表達式execution(* com.spring.service..(..))來決定。
注:以上的理論知識參考:http://www.javashuo.com/article/p-xwxfjphd-bt.html
環境要求
JDK:1.8
SpringBoot:2.2.6.RELEASE
首先仍是Maven的相關依賴,基本和普通springboot項目同樣,就是多了spring-boot-starter-aop
這jar的依賴。
pom.xml文件以下:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.6.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.68</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>test</scope> </dependency> </dependencies>
application.properties
的文件的配置:
banner.charset=UTF-8 server.tomcat.uri-encoding=UTF-8 spring.http.encoding.charset=UTF-8 spring.http.encoding.enabled=true spring.http.encoding.force=true spring.messages.encoding=UTF-8 spring.application.name=springboot-aspect server.port=8180
SpringBoot在使用切面的時候,只須要在自定義的一個切面類中加上 @Aspect
註解進行聲明,而後在自定義切面的類方法中加上對應的註解便可。
好比這裏的示例咱們想作一個請求響應的加解密切面處理,業務層只需關心代碼邏輯實現,而不用關心請求參數和響應參數的加解密實現。那麼首先咱們須要自定義一個加解密的切面類,在該類添加@Aspect
註解,而後在定義一個公共的切入點(Pointcut),指向須要處理的包,而後在定義一個前置通知(添加@Before
註解)和後置通知(添加@AfterReturning
)方法實現便可。
這裏咱們就將切入點設置爲控制層包裏全部的請求。
切入點代碼示例:
@Pointcut("execution(public * com.pancm.web.*.*(..))") public void doOperation() { }
而後在定義一個前置通知,實現對請求參數的數據解密,這裏咱們就用User這個實體類的名稱,對該數據進行解密。實際在運用是能夠根據自身的狀況來編寫。
前置通知代碼示例:
@Before("doOperation()") public void before(JoinPoint joinPoint) throws Throwable{ Object[] objs = joinPoint.getArgs(); for (Object obj : objs) { User user =(User) obj; System.out.println("前置通知接受的參數:"+user); String name =base64DeStr(user.getName()); user.setName(name); } }
在編寫完前置通知的方法以後,咱們在編寫後置通知的代碼,這塊基本和前置通知的同樣,就是把返回的數據進行加密而已。
後置通知代碼示例:
@AfterReturning(returning = "object", pointcut = "doOperation()") public void doAfterReturning(Object object) { ResultBody resultBody = (ResultBody) object; String str =null; try { str=base64EnStr(resultBody.getResult()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } resultBody.setResult(str); System.out.println("後通知響應的參數:"+resultBody); }
完整代碼示例:
@Aspect @Component public class ParamAspect { @Pointcut("execution(public * com.pancm.web.*.*(..))") public void doOperation() { } @Before("doOperation()") public void before(JoinPoint joinPoint) throws Throwable{ Object[] objs = joinPoint.getArgs(); for (Object obj : objs) { User user =(User) obj; System.out.println("前置通知接受的參數:"+user); String name =base64DeStr(user.getName()); user.setName(name); } } @AfterReturning(returning = "object", pointcut = "doOperation()") public void doAfterReturning(Object object) { ResultBody resultBody = (ResultBody) object; String str =null; try { str=base64EnStr(resultBody.getResult()); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } resultBody.setResult(str); System.out.println("前置通知響應的參數:"+resultBody); } public String base64EnStr(String str) throws UnsupportedEncodingException { return Base64.getEncoder().encodeToString(str.getBytes("UTF-8")); } public static String base64DeStr(String encodeStr) throws UnsupportedEncodingException { byte[] decodeStr = Base64.getDecoder().decode(encodeStr); return new String(decodeStr, "UTF-8"); }
實體類代碼
public class User { private Long id; private String name; private Integer age; //getter 和 setter 略 }
控制層z這塊的代碼和普通的同樣,咱們這裏只需簡單的作下處理便可,這裏爲了方便理解,沒有編寫service層和dao的代碼。:
** 控制層代碼**
@RestController @RequestMapping(value = "/api") public class UserRestController { @GetMapping("/user") public ResultBody findByUser(User user) { System.out.println("用戶查詢接口請求的參數:"+user); ResultBody resultBody = new ResultBody(); List<User> userList =new ArrayList<>(); User user2=new User(); user2.setId(1L); user2.setName("xuwujing"); user2.setAge(18); userList.add(user2); resultBody.setCode("0"); resultBody.setResult(userList.toString()); System.out.println("用戶查詢接口響應的參數:"+resultBody); return resultBody; } }
App 入口
和普通的SpringBoot項目基本同樣!
代碼以下:
@SpringBootApplication public class AspectApp { public static void main( String[] args ) { SpringApplication.run(AspectApp.class, args); System.out.println("Aspect啓動成功!"); } }
編寫完代碼以後,咱們啓動程序,由於是Get請求,在瀏覽器或者使用Postman輸入地址均可以進行測試,須要注意的是這裏咱們須要對name的值進行base64加密請求。
輸入:
控制檯打印:
前置通知接受的參數:{"name":"eHV3dWppbmc="}
用戶查詢接口請求的參數:{"name":"xuwujing"}
用戶查詢接口響應的參數:{"code":"0","result":"[{"age":18,"id":1,"name":"xuwujing"}]"}
後通知響應的參數:{"code":"0","result":"W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ=="}
請求響應參數:
{
"code": "0",
"message": null,
"result": "W3siYWdlIjoxOCwiaWQiOjEsIm5hbWUiOiJ4dXd1amluZyJ9XQ=="
}
示例圖:
關於SpringBoot切面Aop的demo簡單講解的文章就講解到這裏了,若有不妥,歡迎指正!
SpringBoot 的aop的項目工程地址:
https://github.com/xuwujing/springBoot-study/tree/master/springboot-aspect
SpringBoot整個集合的地址:
https://github.com/xuwujing/springBoot-study
翩若驚鴻,婉若游龍,榮曜秋菊,華茂春鬆。彷彿兮若輕雲之蔽月,飄飄兮若流風之迴雪。遠而望之,皎若太陽升朝霞;迫而察之,灼若芙蕖出淥波。--網易雲網友評論
原創不易,若是感受不錯,但願給個推薦!您的支持是我寫做的最大動力!
版權聲明:
做者:虛無境
博客園出處:http://www.cnblogs.com/xuwujing
CSDN出處:http://blog.csdn.net/qazwsxpcm
我的博客出處:http://www.panchengming.com