
关于
Quarkus 3.x LTS 架构模式,结合 Camel 消息传递、RESTful API 设计、CDI 服务、Panache 数据访问和异步处理。适用于事件驱动架构的 Java Quarkus 后端开发
name: quarkus-patterns description: Quarkus 3.x LTS 架构模式,包含 Camel 消息传递、RESTful API 设计、CDI 服务、Panache 数据访问和异步处理。适用于基于事件驱动架构的 Java Quarkus 后端开发。 origin: ECC
Quarkus 开发模式
Quarkus 3.x 架构和 API 模式,用于基于 Apache Camel 的云原生、事件驱动服务。
何时激活
- 使用 JAX-RS 或 RESTEasy Reactive 构建 REST API
- 构建 resource → service → repository 分层结构
- 使用 Apache Camel 和 RabbitMQ 实现事件驱动模式
- 配置 Hibernate Panache、缓存或响应式流
- 添加验证、异常映射或分页
- 为 dev/staging/production 环境设置配置文件(YAML 配置)
- 使用 LogContext 和 Logback/Logstash 编码器进行自定义日志记录
- 使用 CompletableFuture 进行异步操作
- 实现条件流处理
- 使用 GraalVM 原生编译
带有多个依赖的服务层
@Slf4j
@ApplicationScoped
@RequiredArgsConstructor
public class OrderProcessingService {
private final OrderValidator orderValidator;
private final EventService eventService;
private final OrderRepository orderRepository;
private final FulfillmentPublisher fulfillmentPublisher;
private final AuditPublisher auditPublisher;
@Transactional
public OrderReceipt process(CreateOrderCommand command) {
ValidationResult validation = orderValidator.validate(command);
if (!validation.valid()) {
eventService.createErrorEvent(command, "ORDER_REJECTED", validation.message());
throw new WebApplicationException(validation.message(), Response.Status.BAD_REQUEST);
}
Order order = Order.from(command);
orderRepository.persist(order);
OrderReceipt receipt = OrderReceipt.from(order);
fulfillmentPublisher.publishAsync(receipt);
auditPublisher.publish("ORDER_ACCEPTED", receipt);
eventService.createSuccessEvent(receipt, "ORDER_ACCEPTED");
log.info("Processed order {}", order.id);
return receipt;
}
}
关键模式:
@RequiredArgsConstructor通过 Lombok 进行构造函数注入@Slf4j用于 Logback 日志记录@Transactional用于通过 Panache 或仓库进行写操作的服务方法- 在持久化或消息发布之前验证输入
- 成功/错误场景的事件跟踪
- 异步 Camel 消息发布
自定义日志上下文模式(Logback)
@ApplicationScoped
public class ProcessingService {
public void processDocument(Document doc) {
LogContext logContext = CustomLog.getCurrentContext();
try (SafeAutoCloseable ignored = CustomLog.startScope(logContext)) {
// Add context to all log statements
logContext.put("documentId", doc.getId().toString());
logContext.put("documentType", doc.getType());
logContext.put("userId", SecurityContext.getUserId());
log.info("Starting document processing");
// All logs within this scope inherit the context
processInternal(doc);
log.info("Document processing completed");
} catch (Exception e) {
log.error("Document processing failed", e);
throw e;
}
}
}
Logback 配置(logback.xml):
<configuration>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<includeContext>true</includeContext>
<includeMdc>true</includeMdc>
</encoder>
</appender>
<logger name="com.example" level="INFO"/>
<root level="WARN">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
事件服务模式
@Slf4j
@ApplicationScoped
@RequiredArgsConstructor
public class EventService {
private final EventRepository eventRepository;
private final ObjectMapper objectMapper;
public void createSuccessEvent(Object payload, String eventType) {
Objects.requireNonNull(payload, "Payload cannot be null");
Event event = new Event();
event.setType(eventType);
event.setStatus(EventStatus.SUCCESS);
event.setPayload(serializePayload(payload));
event.setTimestamp(Instant.now());
eventRepository.persist(event);
log.info("Success event created: {}", eventType);
}
public void createErrorEvent(Object payload, String eventType, String errorMessage) {
Objects.requireNonNull(payload, "Payload cannot be null");
if (errorMessage == null || errorMessage.isBlank()) {
throw new IllegalArgumentException("Error message cannot be blank");
}
Event event = new Event();
event.setType(eventType);
event.set
兼容工具
Claude CodeCursor
标签
后端开发

