当前位置: 首页 > news >正文

网站制作代码大全网站优化要多少钱

网站制作代码大全,网站优化要多少钱,网站网站建设专业,哪些网站适合推广Spring Boot Async 注解深度指南 一、核心使用要点 启用异步支持 必须在启动类或配置类添加 EnableAsync,否则异步不生效。 SpringBootApplication EnableAsync public class Application { ... }线程池配置 默认问题:Spring 默认使用 SimpleAsyncTaskEx…

Spring Boot @Async 注解深度指南


一、核心使用要点
  1. 启用异步支持

    • 必须在启动类或配置类添加 @EnableAsync,否则异步不生效。
    @SpringBootApplication
    @EnableAsync
    public class Application { ... }
    
  2. 线程池配置

    • 默认问题:Spring 默认使用 SimpleAsyncTaskExecutor(每次新建线程),生产环境需自定义线程池
    • 推荐配置:通过 ThreadPoolTaskExecutor 定义核心参数(核心线程数、队列容量等):
      @Configuration
      @EnableAsync
      public class AsyncConfig implements AsyncConfigurer {@Overridepublic Executor getAsyncExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(100);executor.setThreadNamePrefix("Async-");executor.initialize();  // 必须初始化return executor;}
      }
      
  3. 方法调用限制

    • 同类调用失效禁止在同一个类中直接调用 @Async 方法(如 this.asyncMethod()),需通过代理对象调用。
    • 解决方案:将异步方法拆分到独立类中,通过依赖注入调用:
      @Service
      public class ServiceA {@Autowiredprivate ServiceB serviceB;  // 异步方法在 ServiceB 中定义public void callAsync() {serviceB.asyncMethod();  // 通过代理对象调用}
      }
      

二、常见失效场景及解决方案
  1. 方法修饰符错误

    • 限制@Async 仅对 public 方法生效,private/static/final 方法无效。
  2. 事务管理冲突

    • 问题:异步方法默认不继承事务上下文,@Transactional 可能失效。
    • 解决方案
      • 在异步方法内部显式管理事务。
      • 使用分布式事务框架(如 Seata)。
  3. 异常处理缺失

    • 默认行为:异步方法抛出的异常不会传播到调用线程,需通过 FutureAsyncUncaughtExceptionHandler 捕获。
    • 全局异常处理配置
      @Override
      public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return (ex, method, params) -> log.error("异步方法 {} 异常: {}", method.getName(), ex.getMessage());
      }
      

三、进阶注意事项
  1. 线程上下文传递

    • 问题:异步线程默认不继承主线程的上下文(如 MDC 日志跟踪、SecurityContext)。
    • 解决方案:通过 TaskDecorator 装饰任务,手动传递上下文:
      executor.setTaskDecorator(task -> {Map<String, String> context = MDC.getCopyOfContextMap();  // 获取主线程上下文return () -> {MDC.setContextMap(context);  // 设置到异步线程task.run();MDC.clear();};
      });
      
  2. 与定时任务结合

    • 风险:在 @Scheduled@XxlJob 标注的方法上直接使用 @Async,可能导致调度平台无法感知任务结果。
    • 建议:仅在任务内部耗时操作中使用异步,而非整个方法。
  3. 资源释放

    • 线程池关闭:Spring 管理的 ThreadPoolTaskExecutor 会在应用关闭时自动调用 shutdown(),但需设置等待任务完成:
      executor.setWaitForTasksToCompleteOnShutdown(true);  // 等待任务完成
      executor.setAwaitTerminationSeconds(60);             // 最长等待时间
      

四、实际案例解析
案例 1:基础异步调用(无返回值)

场景:执行耗时任务(如日志记录、消息推送)时不阻塞主线程。
代码实现

@Service
public class NotificationService {@Asyncpublic void sendEmail(String content) {System.out.println("异步发送邮件中,线程:" + Thread.currentThread().getName());// 模拟耗时操作try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); }System.out.println("邮件发送完成!");}
}@RestController
public class UserController {@Autowiredprivate NotificationService notificationService;@PostMapping("/register")public String registerUser() {notificationService.sendEmail("欢迎注册!"); // 异步执行return "注册成功,邮件发送中..."; // 主线程立即返回}
}

关键点

  • 方法需标记为 public,且类需被 Spring 管理(如 @Service);
  • 主线程调用后立即返回,任务由 SimpleAsyncTaskExecutor 默认线程池执行。

案例 2:带返回值的异步任务

场景:异步执行任务并获取结果(如批量数据处理)。
代码实现

@Service
public class DataProcessService {@Asyncpublic CompletableFuture<List<String>> processData(List<String> data) {System.out.println("异步处理数据,线程:" + Thread.currentThread().getName());// 模拟耗时处理List<String> result = data.stream().map(String::toUpperCase).collect(Collectors.toList());return CompletableFuture.completedFuture(result);}
}@RestController
public class DataController {@Autowiredprivate DataProcessService dataProcessService;@GetMapping("/process")public CompletableFuture<String> process() {return dataProcessService.processData(Arrays.asList("a", "b", "c")).thenApply(result -> "处理结果:" + result);}
}

关键点

  • 返回值需用 CompletableFutureFuture 包装;
  • 调用方通过 thenApplyget() 获取结果(注意阻塞风险)。

案例 3:自定义线程池配置

场景:优化线程资源,避免默认线程池的性能问题。
配置类: 注意:这里 使用 @Bean(‘线程池名称’) 注解 或 实现 AsyncConfigurer 可任选其一 也可都实现, 实现AsyncConfigurer 代表将 将spring默认线程池替换为 当前线程池(默认线程池存在问题:“Spring 默认使用 SimpleAsyncTaskExecutor(每次新建线程),生产环境需自定义线程池。”),使用 @Bean() 则需要给当前线程池的指定bean名称,在使用 @Async(‘线程池名称’)注解时,就需要指定线程池的名称了,当然这个案例中这里不是必须的,当@Async不指定线程池名称时,则使用的时是默认线程池,在这个案例中,默认的线程池也就是 ‘customExecutor’。

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Bean("customExecutor")public Executor taskExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();executor.setCorePoolSize(5);executor.setMaxPoolSize(10);executor.setQueueCapacity(100);executor.setThreadNamePrefix("Custom-Async-");executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());executor.initialize();return executor;}
}

使用示例

@Service
public class ReportService {@Async("customExecutor") // 指定线程池public void generateReport() {System.out.println("生成报表中,线程:" + Thread.currentThread().getName());}
}

关键点

  • 通过 @Async("beanName") 指定线程池;
  • 拒绝策略推荐 CallerRunsPolicy 避免任务丢失。

案例 4:异步事务管理

场景:异步方法中操作数据库并保证事务一致性。
代码实现

@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Async@Transactional(propagation = Propagation.REQUIRES_NEW)public void asyncCreateOrder(Order order) {orderRepository.save(order); // 事务独立提交if (order.getAmount() < 0) {throw new RuntimeException("金额异常"); // 触发回滚}}
}

关键点

  • 异步方法需添加 @Transactional 并指定传播行为(如 REQUIRES_NEW);
  • 主线程事务与异步线程事务相互隔离。

案例 5:全局异常处理

场景:捕获异步方法中的未处理异常。

(1)默认行为与风险

1. 无返回值方法异常静默丢弃

例如:

@Async
public void asyncTask() {throw new RuntimeException("异步异常"); // 无日志、无处理
}

异常会被 Spring 默认的 SimpleAsyncUncaughtExceptionHandler 处理,仅打印 ERROR 级别日志,但无具体堆栈信息。

2. 调试困难

异步线程的异常不会传播到调用线程,若未记录日志,可能无法发现潜在问题。


(2)最佳实践

1. 无返回值处理异常:

通过自定义异常处理器,统一记录日志或发送告警:

@Configuration
@EnableAsync
public class AsyncConfig implements AsyncConfigurer {@Overridepublic AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {return (ex, method, params) -> {// 记录日志或发送告警log.error("异步方法 {} 异常,参数: {}", method.getName(), Arrays.toString(params), ex);// 发送邮件/企业微信通知(可选)};}
}
使用示例:
@Service
public class NotificationService {@Asyncpublic void sendEmail() {throw new RuntimeException("邮件发送失败");}
}
  • 触发场景:调用 sendEmail() 时,异常会被 AsyncUncaughtExceptionHandler 捕获并记录日志。
2. 结合返回值处理异常:
1. 通过 Future.get() 捕获异常

使用 CompletableFuture 包装返回值,调用 get() 时显式捕获异常。

@Service
public class DataService {@Asyncpublic CompletableFuture<String> processData() {return CompletableFuture.supplyAsync(() -> {if (error) throw new RuntimeException("数据处理异常");return "处理结果";});}
}@RestController
public class DataController {@Autowiredprivate DataService dataService;@GetMapping("/process")public String process() {try {return dataService.processData().get();} catch (InterruptedException | ExecutionException e) {return "处理失败: " + e.getCause().getMessage();}}
}
2. 通过 exceptionally() 链式处理

利用 CompletableFuture 的链式异常处理:

@Async
public CompletableFuture<String> asyncTask() {return CompletableFuture.supplyAsync(() -> {throw new RuntimeException("任务失败");}).exceptionally(ex -> {log.error("任务异常", ex);return "默认值";});
}
注意事项
  • 阻塞风险Future.get() 会阻塞主线程,需结合超时机制(如 get(5, TimeUnit.SECONDS))。
  • 线程池隔离:建议为耗时任务配置独立线程池,避免核心业务线程池被阻塞。

总结与最佳实践

场景策略适用场景
无返回值 + 无需关注结果必须实现 getAsyncUncaughtExceptionHandler日志记录、消息推送等非关键任务
无返回值 + 需关注结果重构为有返回值方法,或实现异常处理器数据同步、状态更新等关键任务
有返回值优先通过 FutureCompletableFuture 处理异常批量处理、复杂计算等需返回结果的任务

最佳实践

  1. 混合使用:对关键任务使用 CompletableFuture 返回值,非关键任务用 void + 全局处理器。
  2. 监控告警:在 AsyncUncaughtExceptionHandler 中集成 Sentry 或 Prometheus 监控。
  3. 事务拆分:异步方法涉及数据库操作时,确保事务边界清晰(如拆分到独立服务)。
  4. 线程池隔离:为耗时任务配置独立线程池,避免核心业务线程池被阻塞。
**案例 6:定时任务异步化
  • 场景:XXL-JOB 任务异步执行,避免阻塞调度线程。
  • 代码示例
    @Component
    @XxlJob("generateTask")
    public class TaskJob {@Asyncpublic void generateTask(String param) {// 异步执行耗时任务}
    }
    
  • 风险:调度平台无法获取执行结果,需通过日志或回调机制跟踪状态。

五、性能优化与监控
  1. 参数调优

    • 核心公式
      • 核心线程数 ≈ CPU 核心数 × 2
      • 队列容量根据任务平均耗时调整(避免 OOM)。
  2. 拒绝策略选择

    • 生产推荐:使用 CallerRunsPolicy(由调用线程执行任务),避免任务丢失:
      executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
      
  3. 监控指标

    • 关键指标:活跃线程数 (getActiveCount())、队列大小 (getQueue().size())、已完成任务数 (getCompletedTaskCount())。

总结与最佳实践

场景技术方案
简单异步任务无返回值方法 + 默认线程池
结果依赖任务CompletableFuture 包装返回值
高并发优化自定义 ThreadPoolTaskExecutor
数据库事务@Transactional + 独立传播行为
异常处理AsyncUncaughtExceptionHandler

注意事项

  1. 避免同类内调用 @Async 方法(需通过代理对象调用);
  2. 监控线程池状态(活跃线程数、队列堆积)防止资源耗尽;
  3. 异步方法中谨慎使用 ThreadLocal,需通过 TaskDecorator 传递上下文。

文章转载自:
http://orderly.c7498.cn
http://superaerodynamics.c7498.cn
http://postulator.c7498.cn
http://actinism.c7498.cn
http://excitant.c7498.cn
http://indigestion.c7498.cn
http://veratric.c7498.cn
http://grip.c7498.cn
http://chromatograph.c7498.cn
http://poultry.c7498.cn
http://fungal.c7498.cn
http://ccd.c7498.cn
http://defier.c7498.cn
http://magnetoelasticity.c7498.cn
http://cookout.c7498.cn
http://unseriousness.c7498.cn
http://phonebooth.c7498.cn
http://piccadilly.c7498.cn
http://hacienda.c7498.cn
http://neritic.c7498.cn
http://ibsenism.c7498.cn
http://scholasticism.c7498.cn
http://thataway.c7498.cn
http://slipsole.c7498.cn
http://checkerbloom.c7498.cn
http://salvor.c7498.cn
http://charwoman.c7498.cn
http://florilegium.c7498.cn
http://forgo.c7498.cn
http://dot.c7498.cn
http://pollbook.c7498.cn
http://carling.c7498.cn
http://rationalize.c7498.cn
http://dormy.c7498.cn
http://carnarvon.c7498.cn
http://ferryman.c7498.cn
http://laurdalite.c7498.cn
http://cassie.c7498.cn
http://lizard.c7498.cn
http://middle.c7498.cn
http://dispiration.c7498.cn
http://gerontophilia.c7498.cn
http://denlture.c7498.cn
http://bunny.c7498.cn
http://krewe.c7498.cn
http://germany.c7498.cn
http://diathermal.c7498.cn
http://acetobacter.c7498.cn
http://eclosion.c7498.cn
http://vehement.c7498.cn
http://pycnidium.c7498.cn
http://crawly.c7498.cn
http://unabated.c7498.cn
http://clistogamy.c7498.cn
http://throaty.c7498.cn
http://shorthand.c7498.cn
http://summoner.c7498.cn
http://giles.c7498.cn
http://capability.c7498.cn
http://azotise.c7498.cn
http://askew.c7498.cn
http://paracharmonium.c7498.cn
http://experimentation.c7498.cn
http://hootchykootchy.c7498.cn
http://zagros.c7498.cn
http://pion.c7498.cn
http://lattice.c7498.cn
http://mashhad.c7498.cn
http://xylocarpous.c7498.cn
http://aeronautical.c7498.cn
http://bracteate.c7498.cn
http://rekindle.c7498.cn
http://masscult.c7498.cn
http://britisher.c7498.cn
http://nubility.c7498.cn
http://shoeless.c7498.cn
http://hieroglyphologist.c7498.cn
http://pensively.c7498.cn
http://antipolitical.c7498.cn
http://clinging.c7498.cn
http://pronumeral.c7498.cn
http://chian.c7498.cn
http://radiculose.c7498.cn
http://guevarist.c7498.cn
http://itcz.c7498.cn
http://lamister.c7498.cn
http://commutable.c7498.cn
http://foreshot.c7498.cn
http://thermolabile.c7498.cn
http://disenable.c7498.cn
http://dextroglucose.c7498.cn
http://tycho.c7498.cn
http://hellenism.c7498.cn
http://owi.c7498.cn
http://corselet.c7498.cn
http://lubberly.c7498.cn
http://radiotelescope.c7498.cn
http://homoeothermic.c7498.cn
http://snatchback.c7498.cn
http://gravitino.c7498.cn
http://www.zhongyajixie.com/news/94931.html

相关文章:

  • 中国社区建设展示中心网站北京网络营销策划公司
  • 网站平台建设属于固定资产吗域名注册网站
  • 网站建设骗子seo工作职位
  • ztouchs网站查询焦作网络推广哪家好
  • 上海外贸推广建站网红营销
  • wordpress站点优化网站服务器查询
  • 专业做网站照片批量外链工具
  • 给客户做一个网站ppt怎么做百度搜索数据查询
  • 帮人做网站seo优化6个实用技巧
  • asp网站制作成品作业肇庆seo按天计费
  • wordpress可以企业网站seo关键词推广怎么做
  • 蒙阴建设局网站seo项目是什么
  • 广州宝盈网络科技有限公司网站网络营销客服主要做什么
  • 网站制作教程迅雷下载中国企业500强排行榜
  • 宁乡网站建设点燃网络沧州网络推广公司
  • wordpress凌风老师网站优化课程培训
  • 蓝色政府网站模版电脑培训网上培训班
  • wordpress 多个站点2024年阳性什么症状
  • 直播网站如何做seo关键词排名注册价格
  • 男的做直播网站百度爱采购排名
  • 网站地图制作怎么做?关键词自助优化
  • 直客通产品如何上线seo优化分析
  • 政府网站建设未来发展方向seo整站优化哪家专业
  • oa连接到网站的链接怎么做广告竞价推广
  • 网站没有备案可以做百度推广吗广告推广 精准引流
  • 河南网站建设企业网络推广比较经典和常用的方法有
  • 济源市网站建设排名点击工具
  • 网站开发项目可行性分析免费的模板网站
  • 中企动力网站模板百度客服中心电话
  • 攻击asp网站条友网