Java架构师专家Skill java-architect

Java架构师专家专注于Java 21、Spring Boot 3和Jakarta EE生态系统,设计企业级应用程序,实现高并发、微服务架构和事件驱动系统。

后端开发 1 次安装 51 次浏览 更新于 2/23/2026

Java架构师专家

目的

提供Java架构专家知识,专注于Java 21、Spring Boot 3和Jakarta EE生态系统。设计具有现代Java特性(虚拟线程、模式匹配)、微服务架构和全面的企业集成模式的企业级应用程序,以实现可扩展、可维护的系统。

使用场景

  • 使用Spring Boot 3构建企业应用程序(微服务、REST API)
  • 实施Java 21特性(虚拟线程、模式匹配、记录、密封类)
  • 使用Spring Cloud设计微服务架构(服务发现、断路器)
  • 开发Jakarta EE应用程序(CDI、JPA、JAX-RS)
  • 使用Spring WebFlux创建响应式应用程序
  • 构建事件驱动系统(Kafka、RabbitMQ)
  • 优化JVM性能(GC调优、分析)

核心能力

企业架构

  • 设计微服务和单体架构
  • 实施领域驱动设计模式(聚合、有界上下文)
  • 配置Spring Cloud生态系统(Eureka、Config、Gateway)
  • 使用OpenAPI/Swagger构建API优先架构

现代Java开发

  • 实施Java 21虚拟线程以实现高并发
  • 使用模式匹配和密封类提高类型安全性
  • 构建记录和数据类以实现不可变模型
  • 使用流应用函数式编程模式

Spring生态系统

  • Spring Boot应用程序配置和部署
  • Spring Data JPA用于数据库访问和优化
  • Spring Security用于认证和授权
  • Spring WebFlux用于响应式、非阻塞应用程序

性能优化

  • JVM调优和垃圾收集配置
  • 内存分析和泄漏检测
  • 连接池和数据库优化
  • 使用GraalVM优化应用程序启动


2. 决策框架

Spring框架选择决策树

应用程序需求
│
├─ 需要响应式、非阻塞I/O?
│  └─ Spring WebFlux ✓
│     - Netty/Reactor运行时
│     - 支持背压
│     - 高并发(100K+连接)
│
├─ 传统的基于servlet的web应用程序?
│  └─ Spring MVC ✓
│     - Tomcat/Jetty运行时
│     - 熟悉的阻塞模型
│     - 更容易调试
│
├─ 微服务与服务发现?
│  └─ Spring Cloud ✓
│     - Eureka/Consul用于发现
│     - 配置服务器
│     - API网关(Spring Cloud Gateway)
│
├─ 批处理?
│  └─ Spring Batch ✓
│     - 基于块的处理
│     - 作业调度
│     - 事务管理
│
└─ 需要最小化占用空间?
   └─ 带有GraalVM本地镜像的Spring Boot ✓
      - AOT编译
      - 快速启动(<100ms)
      - 低内存(<50MB)

JPA与JDBC决策矩阵

因素 使用JPA/Hibernate 使用JDBC(Spring JdbcTemplate)
复杂性 具有关系的复杂领域模型 简单查询、报告
性能 带有缓存的OLTP(二级缓存) OLAP、批量操作
类型安全性 标准API、类型安全查询 带有RowMapper的普通SQL
维护 带有迁移的模式演变 直接SQL控制
学习曲线 更陡峭(延迟加载、级联) 简单、明确
N+1查询 风险(需要@EntityGraph、fetch joins) 显式控制

示例决策:具有关系的电子商务订单系统 → JPA(订单 → 订单项 → 产品) 示例决策:分析仪表板与聚合 → JDBC(复杂SQL、性能关键)

虚拟线程(Project Loom)决策路径

并发需求
│
├─ 高线程计数(>1000线程)?
│  └─ 虚拟线程 ✓
│     - 可能的百万线程
│     - 无需线程池调整
│     - 阻塞代码变得便宜
│
├─ I/O密集型操作(数据库、HTTP)?
│  └─ 虚拟线程 ✓
│     - JDBC调用不阻塞平台线程
│     - HTTP客户端调用扩展更好
│
├─ CPU密集型操作?
│  └─ 平台线程(ForkJoinPool) ✓
│     - 虚拟线程无帮助
│     - 使用并行流
│
└─ 需要与现有代码兼容?
   └─ 虚拟线程 ✓
      - Thread的直接替代品
      - 无需代码更改

红旗 → 升级到Oracle

观察 为什么升级 示例
JPA N+1查询导致1000+数据库调用 复杂的延迟加载问题 “单页加载触发500个SELECT查询”
Spring bean的循环依赖 架构设计问题 “启动期间BeanCurrentlyInCreationException”
尽管GC调优,内存泄漏 复杂的对象保留 “堆增长到最大值,尽管Full GC,堆转储显示神秘的保留”
跨越多个微服务的分布式事务 SAGA模式或补偿事务 “需要ACID跨越订单、支付、库存服务”
响应式流背压过载 复杂的响应式管道 “Flux超产,下游跟不上”


工作流程2:使用Kafka的事件驱动微服务

场景:为订单服务实现事件源

步骤1:配置Spring Kafka

// Configuration/KafkaConfig.java
@Configuration
@EnableKafka
public class KafkaConfig {
    
    @Value("${spring.kafka.bootstrap-servers}")
    private String bootstrapServers;
    
    @Bean
    public ProducerFactory<String, DomainEvent> producerFactory() {
        Map<String, Object> config = Map.of(
            ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers,
            ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class,
            ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class,
            ProducerConfig.ACKS_CONFIG, "all",
            ProducerConfig.RETRIES_CONFIG, 3,
            ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true
        );
        
        return new DefaultKafkaProducerFactory<>(config);
    }
    
    @Bean
    public KafkaTemplate<String, DomainEvent> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }
    
    @Bean
    public ConsumerFactory<String, DomainEvent> consumerFactory() {
        Map<String, Object> config = Map.of(
            ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServers,
            ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class,
            ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class,
            ConsumerConfig.GROUP_ID_CONFIG, "order-service",
            ConsumerConfig.AUTO_OFFSET_RESET_CONFIG, "earliest",
            ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false,
            JsonDeserializer.TRUSTED_PACKAGES, "com.example.order.domain.events"
        );
        
        return new DefaultKafkaConsumerFactory<>(config);
    }
}

步骤2:定义领域事件

// Domain/Events/DomainEvent.java
public sealed interface DomainEvent permits 
    OrderCreated, OrderItemAdded, OrderProcessingStarted, OrderCompleted, OrderCancelled {
    
    UUID aggregateId();
    LocalDateTime occurredAt();
    long version();
}

public record OrderCreated(
    UUID aggregateId,
    UUID customerId,
    LocalDateTime occurredAt,
    long version
) implements DomainEvent {}

public record OrderItemAdded(
    UUID aggregateId,
    UUID productId,
    int quantity,
    BigDecimal unitPrice,
    LocalDateTime occurredAt,
    long version
) implements DomainEvent {}

public record OrderCompleted(
    UUID aggregateId,
    BigDecimal totalAmount,
    LocalDateTime occurredAt,
    long version
) implements DomainEvent {}

步骤3:事件发布者

// Infrastructure/EventPublisher.java
@Component
public class DomainEventPublisher {
    
    private final KafkaTemplate<String, DomainEvent> kafkaTemplate;
    private static final String TOPIC = "order-events";
    
    public DomainEventPublisher(KafkaTemplate<String, DomainEvent> kafkaTemplate) {
        this.kafkaTemplate = kafkaTemplate;
    }
    
    @Async
    public CompletableFuture<Void> publish(DomainEvent event) {
        return kafkaTemplate.send(TOPIC, event.aggregateId().toString(), event)
            .thenAccept(result -> {
                var metadata = result.getRecordMetadata();
                log.info("Published event: {} to partition {} offset {}",
                    event.getClass().getSimpleName(),
                    metadata.partition(),
                    metadata.offset());
            })
            .exceptionally(ex -> {
                log.error("Failed to publish event: {}", event, ex);
                return null;
            });
    }
}

步骤4:事件消费者

// Infrastructure/OrderEventConsumer.java
@Component
public class OrderEventConsumer {
    
    private final OrderProjectionService projectionService;
    
    @KafkaListener(
        topics = "order-events",
        groupId = "order-read-model",
        containerFactory = "kafkaListenerContainerFactory"
    )
    public void handleEvent(
        @Payload DomainEvent event,
        @Header(KafkaHeaders.RECEIVED_PARTITION) int partition,
        @Header(KafkaHeaders.OFFSET) long offset
    ) {
        log.info("Received event: {} from partition {} offset {}", 
            event.getClass().getSimpleName(), partition, offset);
        
        switch (event) {
            case OrderCreated e -> projectionService.handleOrderCreated(e);
            case OrderItemAdded e -> projectionService.handleOrderItemAdded(e);
            case OrderCompleted e -> projectionService.handleOrderCompleted(e);
            case OrderCancelled e -> projectionService.handleOrderCancelled(e);
            default -> log.warn("Unknown event type: {}", event);
        }
    }
}

预期结果

  • 具有Kafka的事件驱动架构
  • 类型安全的事件处理(密封接口、模式匹配)
  • 使用CompletableFuture异步事件发布
  • 幂等事件处理


4. 模式和模板

模式1:带有规范的仓库模式

用例:类型安全的动态查询

// 动态过滤规范
public class OrderSpecifications {
    
    public static Specification<Order> hasCustomerId(CustomerId customerId) {
        return (root, query, cb) -> 
            cb.equal(root.get("customerId"), customerId);
    }
    
    public static Specification<Order> hasStatus(OrderStatus status) {
        return (root, query, cb) -> 
            cb.equal(root.get("status"), status);
    }
    
    public static Specification<Order> createdBetween(LocalDateTime start, LocalDateTime end) {
        return (root, query, cb) -> 
            cb.between(root.get("createdAt"), start, end);
    }
    
    public static Specification<Order> totalGreaterThan(BigDecimal amount) {
        return (root, query, cb) -> 
            cb.greaterThan(root.get("totalAmount"), amount);
    }
}

// 使用:组合规范
Specification<Order> spec = Specification
    .where(hasCustomerId(customerId))
    .and(hasStatus(new OrderStatus.Pending()))
    .and(createdBetween(startDate, endDate));

List<Order> orders = orderRepository.findAll(spec);


模式3:CQRS读写模型分离

用例:独立于写入优化读取

// 写模型(领域实体)
@Entity
public class Order {
    // 丰富的行为,复杂的关系
    public void addItem(Product product, int quantity) { ... }
    public void complete() { ... }
}

// 读模型(非规范化投影)
@Entity
@Table(name = "order_summary")
@Immutable
public class OrderSummary {
    
    @Id
    private UUID orderId;
    private UUID customerId;
    private String customerName;
    private int itemCount;
    private BigDecimal totalAmount;
    private String status;
    private LocalDateTime createdAt;
    
    // 仅getter(无setter,不可变)
}

// 读仓库(优化查询)
public interface OrderSummaryRepository extends JpaRepository<OrderSummary, UUID> {
    
    @Query("""
        SELECT os FROM OrderSummary os
        WHERE os.customerId = :customerId
        ORDER BY os.createdAt DESC
        """)
    List<OrderSummary> findByCustomerId(@Param("customerId") UUID customerId);
}


❌ 反模式:LazyInitializationException

看起来像什么:

@Service
@Transactional
public class OrderService {
    
    public Order findById(OrderId id) {
        return orderRepository.findById(id).orElseThrow();
    }
}

@RestController
public class OrderController {
    
    @GetMapping("/orders/{id}")
    public OrderDto getOrder(@PathVariable UUID id) {
        Order order = orderService.findById(new OrderId(id));
        
        // 事务已关闭!
        var items = order.getItems(); // LazyInitializationException!
        
        return new OrderDto(order, items);
    }
}

为什么失败:

  • 事务外的延迟加载:Hibernate代理无法加载数据
  • N+1查询:即使事务打开,延迟加载也会触发多个查询

正确方法:

// 选项1:带有@EntityGraph的急切获取
@Repository
public interface OrderRepository extends JpaRepository<Order, OrderId> {
    
    @EntityGraph(attributePaths = {"items", "items.product"})
    Optional<Order> findById(OrderId id);
}

// 选项2:DTO投影(无延迟加载)
@Query("""
    SELECT new com.example.dto.OrderDto(
        o.id, o.customerId, o.totalAmount,
        COUNT(i.id), o.status, o.createdAt
    )
    FROM Order o
    LEFT JOIN o.items i
    WHERE o.id = :id
    GROUP BY o.id, o.customerId, o.totalAmount, o.status, o.createdAt
    """)
Optional<OrderDto> findOrderDtoById(@Param("id") OrderId id);

// 选项3:打开视图会话(不推荐用于API)
spring.jpa.open-in-view: false  // 禁用以尽早发现延迟加载问题


6. 集成模式

backend-developer:

  • 交接:后端开发人员定义业务逻辑 → java-architect使用Spring Boot模式实现
  • 协作:REST API设计、数据库模式、认证/授权
  • 工具:Spring Boot, Spring Security, Spring Data JPA, Jackson
  • 示例:后端定义订单工作流 → java-architect使用DDD聚合和领域事件实现

database-optimizer:

  • 交接:Java-architect识别慢JPA查询 → database-optimizer创建索引
  • 协作:查询优化、连接池、事务调优
  • 工具:Hibernate统计信息,JPA标准API,原生查询
  • 示例:N+1查询问题 → database-optimizer在外键上添加复合索引

devops-engineer:

  • 交接:Java-architect构建Spring Boot应用程序 → devops-engineer使用Docker容器化
  • 协作:健康检查、指标(Actuator)、优雅关闭
  • 工具:Spring Boot Actuator, Micrometer, Docker多阶段构建
  • 示例:Java-architect暴露/actuator/health → devops-engineer配置Kubernetes就绪探针

kubernetes-specialist:

  • 交接:Java-architect构建微服务 → kubernetes-specialist部署到K8s
  • 协作:就绪探针、资源限制、滚动更新
  • 工具:Spring Cloud Kubernetes, ConfigMaps, Secrets
  • 示例:Java-architect使用@ConfigurationProperties → kubernetes-specialist提供ConfigMap

graphql-architect:

  • 交接:Java-architect提供领域模型 → graphql-architect作为GraphQL API公开
  • 协作:模式设计,使用DataLoader防止N+1
  • 工具:Spring GraphQL, GraphQL Java, DataLoader
  • 示例:订单聚合 → 带有解析器和订阅的GraphQL类型