ToB企服应用市场:ToB评测及商务社交产业平台

标题: quarkus依赖注入之十一:拦截器高级特性上篇(属性设置和重复使用) [打印本页]

作者: 大连全瓷种植牙齿制作中心    时间: 2023-8-10 07:29
标题: quarkus依赖注入之十一:拦截器高级特性上篇(属性设置和重复使用)
欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览

业务需求设定

  1. public interface SayHello {
  2.     String hello();
  3. }
复制代码
  1. @ApplicationScoped
  2. @Named("A")
  3. public class SayHelloA implements SayHello {
  4.     @Override
  5.     public void hello() {
  6.         Log.info("hello from A");
  7.     }
  8. }
复制代码
  1. @ApplicationScoped
  2. @Named("B")
  3. public class SayHelloB implements SayHello {
  4.     @Override
  5.     public void hello() {
  6.         Log.info("hello from B");
  7.     }
  8. }
复制代码
  1. @ApplicationScoped
  2. @Named("C")
  3. public class SayHelloC implements SayHello {
  4.     @Override
  5.     public void hello() {
  6.         Log.info("hello from C");
  7.     }
  8. }
复制代码
功能实现分析

  1. @ApplicationScoped
  2. @SendMessage(sendType="sms")
  3. public class SayHelloA implements SayHello {
复制代码
  1. @ApplicationScoped
  2. @SendMessage(sendType="sms")
  3. @SendMessage(sendType="email")
  4. public class SayHelloC implements SayHello {
复制代码
编码:定义拦截器

  1. package com.bolingcavalry.interceptor.define;
  2. import javax.enterprise.util.Nonbinding;
  3. import javax.interceptor.InterceptorBinding;
  4. import java.lang.annotation.*;
  5. @InterceptorBinding
  6. @Repeatable(SendMessage.SendMessageList.class)
  7. @Target({ElementType.TYPE, ElementType.METHOD})
  8. @Retention(RetentionPolicy.RUNTIME)
  9. public @interface SendMessage {
  10.     /**
  11.      * 消息类型 : "sms"表示短信,"email"表示邮件
  12.      * @return
  13.      */
  14.     @Nonbinding
  15.     String sendType() default "sms";
  16.     @Target({ElementType.TYPE, ElementType.METHOD})
  17.     @Retention(RetentionPolicy.RUNTIME)
  18.     @interface SendMessageList {
  19.         SendMessage[] value();
  20.     }
  21. }
复制代码
quarkus对重复使用同一拦截器注解的限制


编码:实现拦截器

  1. package com.bolingcavalry.interceptor.impl;
  2. import com.bolingcavalry.interceptor.define.SendMessage;
  3. import com.bolingcavalry.interceptor.define.TrackParams;
  4. import io.quarkus.arc.Priority;
  5. import io.quarkus.arc.runtime.InterceptorBindings;
  6. import io.quarkus.logging.Log;
  7. import javax.interceptor.AroundInvoke;
  8. import javax.interceptor.Interceptor;
  9. import javax.interceptor.InvocationContext;
  10. import java.lang.annotation.Annotation;
  11. import java.util.*;
  12. import static io.quarkus.arc.ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS;
  13. @SendMessage
  14. @Interceptor
  15. public class SendMessageInterceptor {
  16.     @AroundInvoke
  17.     Object execute(InvocationContext context) throws Exception {
  18.         // 先执行被拦截的方法
  19.         Object rlt = context.proceed();
  20.         // 获取被拦截方法的类名
  21.         String interceptedClass = context.getTarget().getClass().getSimpleName();
  22.         // 代码能走到这里,表示被拦截的方法已执行成功,未出现异常
  23.         // 从context中获取通知类型,由于允许重复注解,因此通知类型可能有多个
  24.         List<String> allTypes = getAllTypes(context);
  25.         // 将所有消息类型打印出来
  26.         Log.infov("{0} messageTypes : {1}", interceptedClass, allTypes);
  27.         // 遍历所有消息类型,调用对应的方法处理
  28.         for (String type : allTypes) {
  29.             switch (type) {
  30.                 // 短信
  31.                 case "sms":
  32.                     sendSms();
  33.                     break;
  34.                 // 邮件
  35.                 case "email":
  36.                     sendEmail();
  37.                     break;
  38.             }
  39.         }
  40.         // 最后再返回方法执行结果
  41.         return rlt;
  42.     }
  43.     /**
  44.      * 从InvocationContext中取出所有注解,过滤出SendMessage类型的,将它们的type属性放入List中返回
  45.      * @param invocationContext
  46.      * @return
  47.      */
  48.     private List<String> getAllTypes(InvocationContext invocationContext) {
  49.         // 取出所有注解
  50.         Set<Annotation> bindings = InterceptorBindings.getInterceptorBindings(invocationContext);
  51.         List<String> allTypes = new ArrayList<>();
  52.         // 遍历所有注解,过滤出SendMessage类型的
  53.         for (Annotation binding : bindings) {
  54.             if (binding instanceof SendMessage) {
  55.                allTypes.add(((SendMessage) binding).sendType());
  56.             }
  57.         }
  58.         return allTypes;
  59.     }
  60.     /**
  61.      * 模拟发送短信
  62.      */
  63.     private void sendSms() {
  64.         Log.info("operating success, from sms");
  65.     }
  66.     /**
  67.      * 模拟发送邮件
  68.      */
  69.     private void sendEmail() {
  70.         Log.info("operating success, from email");
  71.     }
  72. }
复制代码
编码:使用拦截器

  1. @ApplicationScoped
  2. @Named("A")
  3. public class SayHelloA implements SayHello {
  4.     @SendMessage
  5.     @Override
  6.     public void hello() {
  7.         Log.info("hello from A");
  8.     }
  9. }
复制代码
  1. @ApplicationScoped
  2. @Named("B")
  3. public class SayHelloB implements SayHello {
  4.     @SendMessage(sendType = "email")
  5.     @Override
  6.     public void hello() {
  7.         Log.info("hello from B");
  8.     }
  9. }
复制代码
  1. @ApplicationScoped
  2. @Named("C")
  3. public class SayHelloC implements SayHello {
  4.     @SendMessage
  5.     @SendMessage(sendType = "email")
  6.     @Override
  7.     public void hello() {
  8.         Log.info("hello from C");
  9.     }
  10. }
复制代码
编码:单元测试

  1. @QuarkusTest
  2. public class SendMessageTest {
  3.     @Named("A")
  4.     SayHello sayHelloA;
  5.     @Named("B")
  6.     SayHello sayHelloB;
  7.     @Named("C")
  8.     SayHello sayHelloC;
  9.     @Test
  10.     public void testSendMessage() {
  11.         sayHelloA.hello();
  12.         sayHelloB.hello();
  13.         sayHelloC.hello();
  14.     }
  15. }
复制代码
运行单元测试


源码下载

名称链接备注项目主页https://github.com/zq2599/blog_demos该项目在GitHub上的主页git仓库地址(https)https://github.com/zq2599/blog_demos.git该项目源码的仓库地址,https协议git仓库地址(ssh)git@github.com:zq2599/blog_demos.git该项目源码的仓库地址,ssh协议
欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4