【Quarkus】基于CDI和拦截器实现AOP功能

Quarkus 基于CDI和拦截器实现AOP功能

在 Quarkus 中实现 AOP(面向切面编程)功能,通常通过使用 CDI(Contexts and Dependency Injection)和拦截器来实现。Quarkus 支持使用标准的 CDI 注解和拦截器机制来进行 AOP 编程。

CDI简介

CDI全称:CONTEXTS AND DEPENDENCY INJECTION

Quarkus DI 解决方案(也称为 ArC)基于 Jakarta 上下文和依赖注入 4.1 规范。它实现了 CDI Lite 规范,并进行了选定的改进,并通过了 CDI Lite TCK。它不实现 CDI Full。另请参阅支持的功能和限制列表

Quarkus DI solution (also called ArC) is based on the Jakarta Contexts and Dependency Injection 4.1specification. It implements the CDI Lite specification, with selected improvements on top, and passes the CDI Lite TCK. It does not implement CDI Full. See also the list of supported features and limitations.

拦截器简介

拦截器用于将横切关注点与业务逻辑分开。有一个单独的规范 - Java 拦截器 - 定义了基本的编程模型和语义。

Interceptors are used to separate cross-cutting concerns from business logic. There is a separate specification - Java Interceptors - that defines the basic programming model and semantics.

实现步骤

  1. 创建自定义注解
  2. 创建拦截器
  3. 应用拦截器
创建自定义注解

Simple Interceptor Binding Example

java 复制代码
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import jakarta.interceptor.InterceptorBinding;

@InterceptorBinding 
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR}) 
@Inherited 
public @interface Logged {
}
  • @InterceptorBinding 这是一个拦截器绑定注解。请参阅以下示例了解其使用方法。
  • @Target 拦截器绑定注解始终放在拦截器类型上,并且可以放在目标类型或方法上。
  • @Inherited 拦截器绑定通常是@Inherited,但不是必须如此。
创建拦截器

Simple Interceptor Example

java 复制代码
import jakarta.annotation.Priority;
import jakarta.interceptor.AroundInvoke;
import jakarta.interceptor.Interceptor;
import jakarta.interceptor.InvocationContext;

@Logged 
@Priority(Interceptor.Priority.APPLICATION)
@Interceptor 
public class LoggingInterceptor {

   @Inject 
   Logger logger;

   @AroundInvoke 
   Object logInvocation(InvocationContext context) {
      // ...log before
      Object ret = context.proceed(); 
      // ...log after
      return ret;
   }

}
  • @Logged 拦截器绑定注解用于将拦截器绑定到 bean。只需使用 @Logged 注释 bean 类,如以下示例所示。
  • @Priority 启用拦截器并影响拦截器的顺序。优先级值较小的拦截器首先被调用。
  • @Interceptor 标记拦截器组件。
  • @Inject 拦截器可以注入依赖项。
  • @AroundInvoke 表示插入业务方法的方法。
  • Object ret = context.proceed(); 继续执行拦截器链中的下一个拦截器或调用被拦截的业务方法。

💡 拦截器的实例是它们拦截的 bean 实例的依赖对象,即为每个拦截的 bean 创建一个新的拦截器实例。

应用拦截器

Simple Example of Interceptor Usage

java 复制代码
import jakarta.enterprise.context.ApplicationScoped;

@Logged  
@ApplicationScoped
public class MyService {
   void doSomething() {
       ...
   }
}
  • 拦截器绑定注解放在一个bean类上,这样所有的业务方法都会被拦截。注解也可以放在单独的方法上,在这种情况下,只有被注解的方法才会被拦截。
  • 请记住,@Logged 注释是@Inherited。如果有一个继承自 MyService 的 bean 类,则 LoggingInterceptor 也将应用于它。
相关推荐
这个昵称不容易1 小时前
SpringBoot「衣依」服装销售平台:144个Java文件180个接口,从挑衣服到收货评价整条链路都在
java·springboot·毕设
计算机毕设定制辅导-无忧学长1 小时前
《基于微信小程序的居家医疗陪护预约系统设计与实现》
java·spring boot·微信小程序·uniapp·居家医疗陪护预约系统
文丑颜不良啊3 小时前
LeetCode2221~2240题目解析
java·leetcode
秋饼3 小时前
Computer Use Agent Java 落地实战:感知-行动循环、执行器与安全围栏生产级实现
java·ai·技术分享·后端开发
wo_jack3 小时前
C++ 入门笔记(十六):第16课 vector 模拟实现十问十答 —— 从三指针到迭代器失效
c++·后端·面试·stl·vector
量化分析码农4 小时前
【Python量化波动率实战 02】波动率会传染:EWMA 指数加权给近期行情更大话语权
后端
文丑颜不良啊5 小时前
LeetCode2161~2180题目解析
java·leetcode
GISer_Jing5 小时前
如何学习Agent
后端·langchain
JWASX6 小时前
【Go】map 源码解析 - group
后端·golang·map·源码分析
文丑颜不良啊7 小时前
LeetCode2141~2160题目解析
java·leetcode