顾乔芝士网

持续更新的前后端开发技术栈

掌握 Spring Boot 7个高级知识点(spring boot技术介绍)

环境:SpringBoot3.4.2



1. 简介

Spring Boot的简洁性常常掩盖了它处理复杂企业需求的强大能力。在本文中,我们将简要介绍7个高级Spring Boot主题,并通过简短的解释和示例来巩固基本理解。

接下来,我们将分别介绍上面的7个高级核心知识点。

2. 实战案例

2.1 使用Resilience4j实现弹性微服务

微服务需要优雅地处理瞬时故障。Resilience4j与Spring Boot集成,提供了断路器(Circuit Breaker)、重试(Retry)和速率限制器(Rate Limiter)等模式。

@Resource
@LoadBalanced
private RestTemplate restTemplate ;
@CircuitBreaker(name = "userService", fallbackMethod = "fallback")
publicString getUserDetails(String userId) {
  return restTemplate.getForObject("http://user-service/users/" + userId, String.class);
}
public String fallback(String userId, Throwable ex) {
  return String.format("失败获取用户【%s】, %s", userId, ex.getMessage()) ;
}

实现步骤:

  • 引入依赖
<dependency>
  <groupId>io.github.resilience4j</groupId>
  <artifactId>resilience4j-spring-boot3</artifactId>
  <version>2.2.0</version>
</dependency>
  • 配置阈值等信息
resilience4j:
  circuitbreaker:
    instances:
      userService:
        failure-rate-threshold: 60
        sliding-window-type: count-based
        sliding-window-size: 3
        minimum-number-of-calls: 3
        wait-duration-in-open-state: 10000

这里的userService就是我们在方法上@CircuitBreaker注解中的name属性值。

更多关于resilience4j教程,请查看下面文章

保障系统稳定,提升接口安全性

推荐学习!拆解Spring Cloud 4大核心组件,彻底搞懂工作原理(断路器Resilience4J)

2.2 使用Actuator自定义监控

Spring Boot Actuator暴露了用于指标、健康检查等功能的端点。通过自定义Actuator,你可以监控特定于应用程序的指标。

@Component
publicclassPackHealthIndicatorimplementsHealthIndicator{
  @Override
  public Health health(){
    boolean isHealthy = checkCustomHealth() ;
    return isHealthy ? Health.up().build() : Health.down().withDetail("Error", "Custom check failed").build() ;
  }


  privatebooleancheckCustomHealth(){
    // 自定义健康检查逻辑
    return true ;
  }
}

如上定义后,输出如下:

实现步骤:

  • 定义bean实现HealthIndicator
  • 实现自定义健康状态的逻辑
  • 访问/actuator/health(我上面改写了路径/ac)

2.3 分布式事务处理

跨多个服务管理事务可能颇具挑战性。可以使用诸如2PC/3PC,TCC,Saga等之类的模式来实现,或者使用Java事务API(JTA)来实现原子性。

使用Spring Boot和Kafka的Saga模式:

订单服务order-service

@KafkaListener(topics = "order-events")
public void processOrder(OrderEvent event) {
  if ("ORDER_CREATED".equals(event.getStatus())) {
      // 处理支付及库存
  }
}

支付服务payment-service

根据处理结果发布成功或失败事件。

关键点:

  • Saga通过事件驱动的工作流确保最终一致性。
  • 像Axon这样的框架或编排工具可以简化实现过程。

有关分布式事务其它方案的实现,请查看下面文章:

实战案例SpringBoot整合Seata AT模式实现分布式事务【超详细】

2.4 使用Cache优化性能

缓存可以减少数据库的访问,从而减轻数据库的压力。

@Cacheable(value = "users", key = "#userId")
public User getUserById(String userId) {
  return userRepository.findById(userId).orElseThrow(() -> new UserNotFoundException(userId));
}

实现步骤:

  • 引入依赖
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- 如果你要使用基于redis的缓存,那么引入下面的依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • 使用相关注解

通过在方法上使用@Cacheable@CacheEvict@CachePut注解。

2.5 简化异步编程

Spring Boot的@Async注解使得异步编程变得直接明了。

@Service
public class EmailService{
@Async
  public void sendEmail(String email, String message) {
    // 模拟耗时
    Thread.sleep(3000) ;
    System.out.printf("发送邮件到: %s%n", email);
  }
}
// 开启异步任务支持
@EnableAsync
@Configuration
public class AsyncConfig{}

通过异步任务能明显加快接口API的响应速度。

注意:@EnableAsync是开启异步功能的关键,不要忘了。

有关异步任务的更多知识,请查看下面文章:

你用错了!详解SpringBoot异步任务&任务调度&异步请求线程池的使用及原理

SpringBoot异步任务@Async你真的会用吗?这6点细节你知道吗?

2.6 Gateway vs. Zuul网关技术

Spring Cloud Gateway是一个响应式API网关,它替代了Netflix Zuul,以提供更好的性能和灵活性。

Gateway关键特性:

  • 路由和过滤
  • 与Resilience4j集成的断路器
  • 支持WebSocket和负载均衡

编程方式配置路由:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder){
  return builder.routes()
    .route("user_route", r -> r.path("/users/**")
          .uri("http://user-service"))
    .build() ;
}

通过编程的方式可以动态的配置路由。

2.7 通过OAuth2或JWT保护应用程序

OAuth2和JWT通常用于保护API的安全性。

生成Token

public String generateToken(UserDetails userDetails) {
  return Jwts.builder()
       .setSubject(userDetails.getUsername())
       .setExpiration(newDate(System.currentTimeMillis() + 1000 * 60 * 60))
       .signWith(SignatureAlgorithm.HS512, "xxxooo")
       .compact();
}

验证Token

public boolean validateToken(String token) {
  Claims claims = Jwts.parser().setSigningKey("xxxooo")
    .parseClaimsJws(token).getBody() ;
  return claims.getExpiration().after(newDate()) ;
}

添加验证过滤器

public class AuthenticationFilter extends GenericFilterBean{


  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
    throws IOException, ServletException {
    try {
      // TODO
      // 验证Token,最终生成Authentication对象
      Authentication authentication = AuthenticationService.getAuthentication((HttpServletRequest) request) ;
      SecurityContextHolder.getContext().setAuthentication(authentication);
    } catch (Exception exp) {
      HttpServletResponse httpResponse = (HttpServletResponse) response;
      httpResponse.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
      httpResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
      PrintWriter writer = httpResponse.getWriter();
      writer.print(exp.getMessage());
      writer.flush();
      writer.close();
      return ;
    }
    filterChain.doFilter(request, response);
  }
}

安全规则配置

@Bean
SecurityFilterChain filterChain(HttpSecurity http)throws Exception {
  http.csrf(AbstractHttpConfigurer::disable)
      .authorizeHttpRequests(registry -> registry.requestMatchers("/**").authenticated())
      // 可有可无,该配置注册BasicAuthenticationFilter过滤器读取header中的Authorization header数据,值以Basic 开头 
      .httpBasic(Customizer.withDefaults())
      .sessionManagement(hssmc -> hssmc.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
      // 这里添加的优先级是高于上面的BasicAuthenticationFilter
      .addFilterBefore(new AuthenticationFilter(), UsernamePasswordAuthenticationFilter.class) ;
  return http.build();
}

以上就完成了简单的基于JWT的接口安全验证。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言