写点什么

5 个 Spring 异步与事件注解:解耦与高性能注解应用案例 (必须收藏)

作者:肖哥弹架构
  • 2024-08-22
    河北
  • 本文字数:4055 字

    阅读完需:约 13 分钟

5个Spring 异步与事件注解:解耦与高性能注解应用案例(必须收藏)

Spring 框架通过其丰富的注解如@EnableAsync@Async,为应用提供了强大的异步处理能力,允许开发者轻松地将方法调用异步化,有效提升应用的响应性和吞吐量。同时,事件发布和监听机制,以@EventLog@EventListener注解为代表,使得应用组件之间的解耦和交互更加灵活。这些注解的结合使用,为构建复杂而高效的企业级应用提供了强有力的支持。


肖哥弹架构 跟大家“弹弹” 框架注解使用,需要代码关注

欢迎 点赞,关注,评论。

关注公号 Solomon 肖哥弹架构获取更多精彩内容

历史热点文章

1、异步执行

@EnableAsync

  • 注解作用介绍


@EnableAsync 注解用于在配置类上开启对异步方法的支持。


  • 注解属性介绍


无属性。


  • 注解业务案例


@Configuration@EnableAsyncpublic class AsyncConfig {    // 配置异步相关的Bean}
复制代码

@Async

  • 注解作用介绍


@Async 注解用于声明一个方法为异步执行的方法。


  • 注解属性介绍

  • value 或 methodName: 指定执行异步操作的线程池名称。

  • 注解业务案例


@Servicepublic class AsyncService {
@Async("myAsyncExecutor") public void performAsyncTask() { // 异步执行的逻辑 }}
复制代码

2、事件发布与监听

@EnableEventLog

  • 注解作用介绍


@EnableEventLog 注解用于开启事件的日志记录功能(如果有自定义实现)。


  • 注解属性介绍


无属性。


  • 注解业务案例


@Configuration@EnableEventLogpublic class EventLogConfig {    // 配置事件日志相关的Bean}
复制代码

@EventLog

  • 注解作用介绍


@EventLog 注解用于声明一个方法在执行后发布一个事件。


  • 注解属性介绍

  • value: 指定事件的类型。

  • 注解业务案例


public class EventService {    @EventLog("userCreatedEvent")    public void registerUser(User user) {        // 用户注册逻辑    }}
复制代码

@EventListener

  • 注解作用介绍


@EventListener 注解用于声明一个方法为事件监听器。


  • 注解属性介绍

  • value: 指定监听的事件类型。

  • condition: 指定条件表达式,用于决定是否处理事件。

  • 注解业务案例


public class EventConsumer {
@EventListener(UserCreatedEvent.class) public void onUserCreated(UserCreatedEvent event) { // 处理用户创建事件 }}
复制代码

3、条件化配置

@Conditional

  • 注解作用介绍


@Conditional 注解用于根据条件包含配置。


  • 注解属性介绍

  • value: 指定条件类。

  • 注解业务案例


public class MyConditionalConfig {
@Bean @Conditional("#{beanFactory.containsBean('someBean')}") @Conditional(MyCustomCondition.class) public SomeBean someBean() { return new SomeBean(); }}
复制代码

4、异步注解综合案例

import org.springframework.aop.framework.autoproxy.AsyncAnnotationBeanPostProcessor;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.Async;import org.springframework.scheduling.annotation.EnableAsync;import org.springframework.scheduling.annotation.AsyncConfigurer;import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;import org.springframework.stereotype.Service;
import java.util.concurrent.Callable;import java.util.concurrent.Future;import java.util.concurrent.ThreadPoolExecutor;
// 配置类,用于开启异步支持和自定义线程池@Configuration@EnableAsyncpublic class AsyncConfig implements AsyncConfigurer {
// 定义异步任务执行器 @Override public Executor getAsyncExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(2); // 设置核心线程数 executor.setMaxPoolSize(5); // 设置最大线程数 executor.setQueueCapacity(10); // 设置队列容量 executor.setThreadNamePrefix("Async-Thread-"); // 设置线程名前缀 executor.initialize(); return executor; }
// 异常处理器,用于处理异步方法抛出的异常 @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return new AsyncUncaughtExceptionHandler() { @Override public void handleUncaughtException(Throwable ex, Method method, Object... params) { System.out.println("Async method " + method.getName() + " threw an exception: " + ex.toString()); } }; }}
// 业务服务类,包含异步方法@Servicepublic class AsyncService {
// 异步方法,无返回值 @Async public void processOrder(Order order) { try { // 耗时的订单处理过程 Thread.sleep(3000); System.out.println("Order processed in thread: " + Thread.currentThread().getName()); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } }
// 异步方法,有返回值,返回Future对象 @Async public Future<String> fetchDataFromRemoteService() { try { //远程服务获取数据的过程 Thread.sleep(2000); return new AsyncResult<>("Data fetched successfully"); } catch (InterruptedException e) { Thread.currentThread().interrupt(); return new AsyncResult<>(null); } }}
// 订单实体类class Order { // 订单相关信息}
// 应用程序主入口public class AsyncApplication {
public static void main(String[] args) { // 启动Spring应用上下文 }}
复制代码


  • AsyncConfig 类通过实现 AsyncConfigurer 接口来配置异步任务执行器(线程池)和异步方法的异常处理器。

  • AsyncService 类中的 processOrder 方法和 fetchDataFromRemoteService 方法被标记为 @Async,表示它们将在异步执行器配置的线程池中异步执行。

  • processOrder 方法了处理订单的耗时操作,而 fetchDataFromRemoteService 方法从远程服务获取数据的操作,并返回 Future 对象。

  • 异步方法抛出的异常将由 AsyncConfig 类中的异常处理器捕获并记录。

5、事件注解综合案例

1. 定义事件

首先定义一个应用事件UserRegisteredEvent,它扩展了 Spring 的ApplicationEvent类。


import org.springframework.context.ApplicationEvent;public class UserRegisteredEvent extends ApplicationEvent {    private User user;
public UserRegisteredEvent(User user) { super(user); // 将用户信息作为事件的来源 this.user = user; }
public User getUser() { return user; }}
复制代码

2. 创建事件发布方法

在用户服务UserService中,创建一个方法来发布UserRegisteredEvent事件。


import org.springframework.context.ApplicationContext;import org.springframework.stereotype.Service;
@Servicepublic class UserService {
private final ApplicationContext applicationContext;
public UserService(ApplicationContext applicationContext) { this.applicationContext = applicationContext; }
public void registerUser(User user) { // 注册用户逻辑 applicationContext.publishEvent(new UserRegisteredEvent(user)); }}
复制代码

3. 使用@EventListener监听事件

然后,我们创建一个邮件发送服务EmailService,它将监听UserRegisteredEvent事件并发送邮件。


import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;
@Servicepublic class EmailService {
@EventListener @Async // 异步发送邮件,提高性能 public void onUserRegistered(UserRegisteredEvent event) { User user = event.getUser(); // 发送欢迎邮件逻辑 sendWelcomeEmail(user); }
private void sendWelcomeEmail(User user) { // 实际发送邮件的代码 }}
复制代码

4. (可选)使用@EventLog记录事件

如果我们想要记录所有用户注册事件,可以创建一个自定义的@EventLog注解,并在事件监听器中使用它。


@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public @interface EventLog {    String value();}
@Servicepublic class LoggingService {
@EventLog("userRegistered") public void logUserRegistration(UserRegisteredEvent event) { // 记录事件到日志系统的逻辑 logRegistration(event.getUser()); }
private void logRegistration(User user) { // 实际记录日志的代码 }}
复制代码


请注意,@EventLog是一个自定义注解,Spring 框架本身并不提供此注解。在实际应用中,您可能需要实现自定义的日志记录逻辑。

5. 配置 Spring 以支持异步事件监听器

最后,确保 Spring 配置支持异步事件监听器,这可以通过在配置类上添加@EnableAsync注解来实现。


import org.springframework.context.annotation.Configuration;import org.springframework.scheduling.annotation.EnableAsync;
@Configuration@EnableAsyncpublic class AsyncConfig { // 异步配置}
复制代码


发布于: 刚刚阅读数: 5
用户头像

智慧属心窍之锁 2019-05-27 加入

擅长于通信协议、微服务架构、框架设计、消息队列、服务治理、PAAS、SAAS、ACE\ACP、大模型

评论

发布
暂无评论
5个Spring 异步与事件注解:解耦与高性能注解应用案例(必须收藏)_spring_肖哥弹架构_InfoQ写作社区