通過編碼實戰瞭解quarkus攔截器的另一個高級特性:禁用類級別攔截器,這樣可以避免類級別和方法級別攔截器的疊加衝突 ...
歡迎訪問我的GitHub
這裡分類和彙總了欣宸的全部原創(含配套源碼):https://github.com/zq2599/blog_demos
本篇概覽
- 本篇是《quarkus依賴註入》系列的第十二篇,繼續學習攔截器的另一個高級特性:禁用類級別攔截器
- 本篇由以下內容構成
- 編碼驗證類攔截器和方法攔截器的疊加效果
- 用註解NoClassInterceptors使類攔截器失效
- 總的來說,本篇內容非常簡單,就是說清楚NoClassInterceptors註解用在哪裡,怎麼用,可以輕鬆愉快的閱讀
類攔截器和方法攔截器的疊加效果
- 接下來進行編碼,看看作用在類上和方法上的兩個攔截器的疊加效果,要新建的文件清單如下
- TrackClass.java:定義類級別的攔截器
- TrackClassInterceptor.java:攔截器TrackClass的功能實現
- TrackMethod.java:方法級別的攔截器
- TrackMethodInterceptor.java:攔截器TrackMethod的功能實現
- ExcludeInterceptorDemo.java:普通的bean,用TrackClass修飾其類,用TrackMethod修飾其test1方法
- ExcludeInterceptorTest.java:單元測試類,運行ExcludeInterceptorDemo的方法,觀察攔截效果
- 以下是每個文件的詳細內容
- 第一個攔截器TrackClass,用來修飾類,對類的每個方法都有攔截效果
@InterceptorBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackClass {
}
- TrackClass的攔截功能實現類TrackClassInterceptor
@TrackClass
@Interceptor
public class TrackClassInterceptor {
@AroundInvoke
Object execute(InvocationContext context) throws Exception {
Log.info("from TrackClass");
return context.proceed();
}
}
- 第二個攔截器TrackMethod,用來修飾方法,只對被修飾的方法有攔截效果
@InterceptorBinding
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TrackMethod {
}
- TrackMethod的攔截功能實現類TrackMethodInterceptor
@TrackMethod
@Interceptor
public class TrackMethodInterceptor {
@AroundInvoke
Object execute(InvocationContext context) throws Exception {
Log.info("from TrackMethod");
return context.proceed();
}
}
- 為了演示攔截器的效果,創建一個bean,如下所示,TrackClass修飾在類上面,所以test0和test1方法都會被TrackClassInterceptor攔截,另外,test1方法還會被TrackMethodInterceptor,也就是說兩個攔截器都會攔截test1方法
@ApplicationScoped
@TrackClass
public class ExcludeInterceptorDemo {
public void test0() {
Log.info("from test0");
}
@TrackMethod
public void test1() {
Log.info("from test1");
}
}
- 用單元測試類驗證效果
@QuarkusTest
public class ExcludeInterceptorTest {
@Inject
ExcludeInterceptorDemo excludeInterceptorDemo;
@Test
public void test() {
excludeInterceptorDemo.test0();
Log.info("*****************************");
excludeInterceptorDemo.test1();
}
}
- 運行效果如下,可見test0被類攔截器攔截,而test1先後被類攔截器和方法攔截器攔截
- 當然了,以上一切都是符合預期的,並沒有什麼問題
用註解NoClassInterceptors使類攔截器失效
- 假設遇到了某些衝突(例如和資料庫、IO相關等),導致TrackClassInterceptor和TrackMethodInterceptor兩個攔截器不能同時對test1方法進行攔截,只能保留TrackMethodInterceptor
- 此時,可以用註解NoClassInterceptors修飾test1方法,如下圖紅框所示,這樣類攔截器TrackClassInterceptor就會失效,只剩下TrackMethodInterceptor可以正常工作
![image-20220502192040472](https://img2023.cnblogs.com/blog/485422/202308/485422-20230805163015557-81818539.png)
- 再次執行單元測試,效果如下圖,可見類攔截器TrackClassInterceptor不再攔截被NoClassInterceptors修飾的test1方法
![image-20220502192714034](https://img2023.cnblogs.com/blog/485422/202308/485422-20230805163015562-1710181276.png)
NoClassInterceptors的影響範圍
- 回顧類攔截器TrackClassInterceptor,如下圖紅框,可見其攔截方法有註解AroundInvoke修飾
![image-20220502193918403](https://img2023.cnblogs.com/blog/485422/202308/485422-20230805163015517-1230804564.png)
- 而NoClassInterceptors的作用,就是針對有註解AroundInvoke修飾的方法,使他們失效
- 除了AroundInvoke,NoClassInterceptors還針對AroundConstruct修飾的方法,使他們失效
- 至此,攔截器的高級特性已經全部學習和實踐完成,希望能給您提供一些參考,助您設計出更完善的攔截器
源碼下載
- 本篇實戰的完整源碼可在GitHub下載到,地址和鏈接信息如下表所示(https://github.com/zq2599/blog_demos)
名稱 | 鏈接 | 備註 |
---|---|---|
項目主頁 | https://github.com/zq2599/blog_demos | 該項目在GitHub上的主頁 |
git倉庫地址(https) | https://github.com/zq2599/blog_demos.git | 該項目源碼的倉庫地址,https協議 |
git倉庫地址(ssh) | [email protected]:zq2599/blog_demos.git | 該項目源碼的倉庫地址,ssh協議 |
- 這個git項目中有多個文件夾,本次實戰的源碼在quarkus-tutorials文件夾下,如下圖紅框
- quarkus-tutorials是個父工程,裡面有多個module,本篇實戰的module是basic-di,如下圖紅框