设为首页 加入收藏

TOP

quarkus依赖注入之十一:拦截器高级特性上篇(属性设置和重复使用)(二)
2023-08-26 21:11:17 】 浏览:78
Tags:quarkus 赖注入 十一 高级特
e com.bolingcavalry.interceptor.impl; import com.bolingcavalry.interceptor.define.SendMessage; import com.bolingcavalry.interceptor.define.TrackParams; import io.quarkus.arc.Priority; import io.quarkus.arc.runtime.InterceptorBindings; import io.quarkus.logging.Log; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; import java.lang.annotation.Annotation; import java.util.*; import static io.quarkus.arc.ArcInvocationContext.KEY_INTERCEPTOR_BINDINGS; @SendMessage @Interceptor public class SendMessageInterceptor { @AroundInvoke Object execute(InvocationContext context) throws Exception { // 先执行被拦截的方法 Object rlt = context.proceed(); // 获取被拦截方法的类名 String interceptedClass = context.getTarget().getClass().getSimpleName(); // 代码能走到这里,表示被拦截的方法已执行成功,未出现异常 // 从context中获取通知类型,由于允许重复注解,因此通知类型可能有多个 List<String> allTypes = getAllTypes(context); // 将所有消息类型打印出来 Log.infov("{0} messageTypes : {1}", interceptedClass, allTypes); // 遍历所有消息类型,调用对应的方法处理 for (String type : allTypes) { switch (type) { // 短信 case "sms": sendSms(); break; // 邮件 case "email": sendEmail(); break; } } // 最后再返回方法执行结果 return rlt; } /** * 从InvocationContext中取出所有注解,过滤出SendMessage类型的,将它们的type属性放入List中返回 * @param invocationContext * @return */ private List<String> getAllTypes(InvocationContext invocationContext) { // 取出所有注解 Set<Annotation> bindings = InterceptorBindings.getInterceptorBindings(invocationContext); List<String> allTypes = new ArrayList<>(); // 遍历所有注解,过滤出SendMessage类型的 for (Annotation binding : bindings) { if (binding instanceof SendMessage) { allTypes.add(((SendMessage) binding).sendType()); } } return allTypes; } /** * 模拟发送短信 */ private void sendSms() { Log.info("operating success, from sms"); } /** * 模拟发送邮件 */ private void sendEmail() { Log.info("operating success, from email"); } }
  • 上述代码,有以下几处需要注意
  1. 发送短信和邮件不是本篇的重点,因此,对应的sendSms和sendEmail方法中只是日志打印,表示代码已经走到了此处
  2. getAllTypes方法是重点,演示了如何从拦截器上下文对象invocationContext中获取所有注解,并过滤出所有SendMessage类型,再取其type属性
  3. 对取出的sendType属性逐一处理,这样就做到了每个设置的类型都会被处理
  4. 在某个方法上多次用SendMessage注解修饰,最终只会执行一次SendMessageInterceptor#execute方法,这是关键!试想,如果SendMessageInterceptor#execute方法执行了多次,而每次都会取出所有SendMessage类型去处理,那么每种SendMessage类型都会重复处理

编码:使用拦截器

  • 拦截器的定义和实现都已经完成,接下来就是使用拦截器了,注意前面提到的限制,这里要用SendMessage去修饰方法,而不能修饰类
  1. 首先是SayHelloA,拦截它的时候,业务需求是发送短信,修改后的完整源码如下,用SendMessage注解修饰hello方法,这里的SendMessage没有指定其sendType的值,因此会使用默认值sms
@ApplicationScoped
@Named("A")
public class SayHelloA implements SayHello {

    @SendMessage
    @Override
    public void hello() {
        Log.info("hello from A");
    }
}
  1. 然后是SayHelloB,拦截它的时候,业务需求是发送邮件,注意sendType值等于email
@ApplicationScoped
@Named("B")
public class SayHelloB implements SayHello {

    @SendMessage(sendType = "email")
    @Override
    public void hello() {
        Log.info("hello from B");
    }
}
  1. 最后是SayHelloC,拦截它的时候,也无需求是短信和邮件都要发送,注意这里使用了两次SendMessage
@ApplicationScoped
@Named("C")
public class SayHelloC implements SayHello {

    @SendMessage
    @SendMessage(sendType = "email")
    @Ove
首页 上一页 1 2 3 下一页 尾页 2/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇SpringBoot配置文件脱敏 下一篇Java源代码是如何编译,加载到内..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目