设为首页 加入收藏

TOP

quarkus依赖注入之十一:拦截器高级特性上篇(属性设置和重复使用)(一)
2023-08-26 21:11:17 】 浏览:67
Tags:quarkus 赖注入 十一 高级特

欢迎访问我的GitHub

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

本篇概览

  • 本篇是《quarkus依赖注入》系列的第十一篇,之前的[《拦截器》]学习了拦截器的基础知识,现在咱们要更加深入的了解拦截器,掌握两种高级用法:拦截器属性和重复使用拦截器
  • 先来回顾拦截器的基本知识,定义一个拦截器并用来拦截bean中的方法,总共需要完成以下三步
    流程图 (4)

业务需求设定

  • 为了让本篇所学知识点显得有实用型,这里假定一个业务需求,然后咱们用拦截器来满足这个需求
  • 假设有个名为SayHello的普通接口,此接口有三个实现类:SayHelloA、SayHelloB、SayHelloC,这些实现类都是bean,它们的源码如下
  1. 接口SayHello.java
public interface SayHello {
    String hello();
}
  1. 实现类SayHelloA.java
@ApplicationScoped
@Named("A")
public class SayHelloA implements SayHello {
    @Override
    public void hello() {
        Log.info("hello from A");
    }
}
  1. 实现类SayHelloB.java
@ApplicationScoped
@Named("B")
public class SayHelloB implements SayHello {
    @Override
    public void hello() {
        Log.info("hello from B");
    }
}
  1. 实现类SayHelloC.java
@ApplicationScoped
@Named("C")
public class SayHelloC implements SayHello {
    @Override
    public void hello() {
        Log.info("hello from C");
    }
}
  • 以上是已知条件,现在来看业务需求
  1. 要求设计一个拦截器,名为SendMessage,功能是对外发送通知,通知的方式有短信和邮件两种,具体用哪种是可以设置的
  2. SendMessage拦截器拦截SayHelloA,通知类型是短信
  3. SendMessage拦截器拦截SayHelloB,通知类型是邮件
  4. SendMessage拦截器拦截SayHelloC,通知类型是短信和邮件都发送

功能实现分析

  • 上述业务需求第二项和第三项,很显然拦截器的实现要同时支持短信通知和邮件通知两种功能,而问题的关键是:拦截器在工作的时候,如何知道当前应该发送短信还是邮件,或者说如何将通知类型准确的告诉拦截器?
  • 这就牵扯到一个知识点:拦截器属性,拦截器自己是个注解,而注解是有属性的,咱们新增一个通知类型的属性(名为sendType),只要在使用注解的地方配置sendType,然后在拦截器实现中获取到sendType的值,就解决了通知类型的设置和获取的问题,业务需求2和3也就迎刃而解了,拦截器配置的效果大致如下
@ApplicationScoped
@SendMessage(sendType="sms")
public class SayHelloA implements SayHello {
  • 再来看需求4,这又设计到拦截器的另一个知识点:同一个拦截器重复使用,只要连续两次用SendMessage注解修饰SayHelloC,而每个注解的sendType分别是短信和邮件,这样就能达到目的了,拦截器配置的效果大致如下
@ApplicationScoped
@SendMessage(sendType="sms")
@SendMessage(sendType="email")
public class SayHelloC implements SayHello {
  • 以上就是解决问题的大致思路,接下来编码实现,将涉及的知识点在代码中体现出来

编码:定义拦截器

  • 首先是拦截器定义SendMessage.java,有几处要注意的地方稍后会提到
package com.bolingcavalry.interceptor.define;

import javax.enterprise.util.Nonbinding;
import javax.interceptor.InterceptorBinding;
import java.lang.annotation.*;

@InterceptorBinding
@Repeatable(SendMessage.SendMessageList.class)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface SendMessage {

    /**
     * 消息类型 : "sms"表示短信,"email"表示邮件
     * @return
     */
    @Nonbinding
    String sendType() default "sms";

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @interface SendMessageList {
        SendMessage[] value();
    }
}
  • 上述代码有以下几处需要注意
  1. 允许在同一位置重复使用同一个注解,这是java注解的通用功能,并非quarkus独有
  2. 重复使用注解时,必须定义注解容器,用来放置重复的注解,这里的容器是SendMessageList
  3. 使用Repeatable修饰SendMessage,这样就能在同一位置重复使用SendMessage注解了,注意Repeatable的属性值是容器SendMessageList
  4. sendType是注解属性,用来保存通知类型,任何使用SendMessage注解的地方都能通过设置sendType来指定通知类型,如果不指定则使用默认值sms
  5. 要注意sendType的注解Nonbinding,此注解非常重要,如果不添加此注解,在使用SendMessage的时候,设置sendType为email时拦截器不会生效

quarkus对重复使用同一拦截器注解的限制

  • 虽然可以在同一位置重复使用SendMessage拦截器,但是要注意quarkus的限制
  1. 可以作用在方法上
  2. 不能作用在类上
  3. 不能作用在stereotypes上
  • 关于2和3,官方的说法是将来会解决(This might be added in the future)

编码:实现拦截器

  • 接下来是实现具体拦截功能的SendMessageInterceptor.java,代码如下,有几处要注意的地方稍后会提到
packag
首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇SpringBoot配置文件脱敏 下一篇Java源代码是如何编译,加载到内..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目