Springboot event Listener 事件监听 异步处理

本文展示了如何在Spring应用中实现SpringContextHolder以获取ApplicationContext,并创建SplitEvent事件及监听器SplitListener。通过Spring的事件发布机制,SplitListener异步处理事件,延迟10秒打印 UserService 的名称。在启动类中配置了事件监听器并提供了测试接口。
摘要由CSDN通过智能技术生成

编写SpringContextHolder


package com.cf.user.server.event;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

/**
 * SpringContextHolder
 */
@Slf4j
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {

	private static ApplicationContext applicationContext = null;

	/**
	 * 取得存储在静态变量中的ApplicationContext.
	 */
	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}

	/**
	 * 实现ApplicationContextAware接口, 注入Context到静态变量中.
	 */
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) {
		SpringContextHolder.applicationContext = applicationContext;
	}

	/**
	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(String name) {
		return (T) applicationContext.getBean(name);
	}

	/**
	 * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
	 */
	public static <T> T getBean(Class<T> requiredType) {
		return applicationContext.getBean(requiredType);
	}

	/**
	 * 清除SpringContextHolder中的ApplicationContext为Null.
	 */
	public static void clearHolder() {
		if (log.isDebugEnabled()) {
			log.debug("清除SpringContextHolder中的ApplicationContext:" + applicationContext);
		}
		applicationContext = null;
	}

	/**
	 * 发布事件
	 * @param event
	 */
	public static void publishEvent(ApplicationEvent event) {
		if (applicationContext == null) {
			return;
		}
		applicationContext.publishEvent(event);
	}

	/**
	 * 实现DisposableBean接口, 在Context关闭时清理静态变量.
	 */
	@Override
	@SneakyThrows
	public void destroy() {
		SpringContextHolder.clearHolder();
	}

}

定义事件 SplitEvent

package com.cf.user.server.event;

import org.springframework.context.ApplicationEvent;

/**
 * @Description: 事件定义
 */
public class SplitEvent extends ApplicationEvent {
    public SplitEvent(Object source) {
        super(source);
    }
}

事件监听

package com.cf.user.server.event;

import cn.hutool.core.date.DateUtil;
import com.cf.user.server.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;

/**
 * @Description: 事件监听器
 */
@Slf4j
@RequiredArgsConstructor
public class SplitListener {

    private final UserService service;

    @Async
    @Order
    @EventListener(SplitEvent.class)
    public void doSplit(SplitEvent event) throws InterruptedException {
        log.info("事件处理---");
        Thread.sleep(10000);
        // event.getSource 接收Object类型的参数
        Integer num = (Integer) event.getSource();
        for (int i = 0; i < num; i++) {
            String name = service.getName();
            log.info(name);
        }
    }
}

UserService方法

package com.cf.user.server.service.impl;

import com.cf.user.server.service.UserService;
import org.apache.catalina.User;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    @Override
    public String getName() {
        return "张三";
    }
}

Application 启动类配置

package com.cf.user.server;

import com.cf.user.server.event.SplitListener;
import com.cf.user.server.service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;

@EnableAsync
@ComponentScan(basePackages = {
        "com.cf.user.server.*"
})
@SpringBootApplication
public class UserServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(UserServerApplication.class, args);
    }

    /**
     * 注入监听器
     */
    @Bean
    public SplitListener sysLogListener(UserService userService) {
        return new SplitListener(userService);
    }
}

DemoController

package com.cf.user.server.controller;

import com.cf.user.server.event.SplitEvent;
import com.cf.user.server.event.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping("demo")
public class DemoController {

    @GetMapping
    public String test(){
    	// 给SplitEvent传入数字参数
        SpringContextHolder.publishEvent(new SplitEvent(2));
        log.info("return-----");
        return "abc";
    }

}

在这里插入图片描述
摘自Pig项目
Gitee地址

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot中,可以使用事件机制来实现异步事件处理异步事件可以在应用程序中的不同组件之间进行通信,以实现解耦和并发处理。 要使用Spring Boot的事件机制,首先需要定义一个事件类,该类表示要发布的事件。事件类可以是普通的POJO类,通常包含一些必要的属性和方法。 然后,需要定义一个事件监听器类,该类用于处理特定类型的事件。监听器类需要实现`ApplicationListener`接口,并通过泛型指定要监听的事件类型。在监听器类中,可以定义一个或多个处理事件的方法。 接下来,需要在应用程序中触发事件。可以通过使用`ApplicationEventPublisher`接口中的`publishEvent()`方法来发布事件。该接口可以通过自动装配的方式注入到需要触发事件的组件中。 最后,当触发事件时,监听器类中相应的方法将被调用来处理事件。如果希望异步处理事件,可以在监听器类中使用`@Async`注解来标记处理方法,以便在单独的线程中执行。 以下是一个简单的示例代码,演示了如何在Spring Boot中实现异步事件处理: ```java // 定义事件类 public class MyEvent extends ApplicationEvent { private String message; public MyEvent(Object source, String message) { super(source); this.message = message; } public String getMessage() { return message; } } // 定义事件监听器类 @Component public class MyEventListener implements ApplicationListener<MyEvent> { @Async @Override public void onApplicationEvent(MyEvent event) { System.out.println("Received event: " + event.getMessage()); // 处理事件逻辑 } } // 触发事件的组件 @Component public class EventTriggerComponent { @Autowired private ApplicationEventPublisher eventPublisher; public void triggerEvent(String message) { MyEvent event = new MyEvent(this, message); eventPublisher.publishEvent(event); } } ``` 在上述示例中,`MyEvent`表示自定义的事件类,`MyEventListener`是事件监听器类,`EventTriggerComponent`是触发事件的组件。 当调用`EventTriggerComponent`的`triggerEvent()`方法时,会发布一个`MyEvent`事件,然后`MyEventListener`中的`onApplicationEvent()`方法将被异步调用来处理该事件。 需要注意的是,为了让Spring Boot支持异步事件处理,还需要在配置类中添加`@EnableAsync`注解。 这就是使用Spring Boot实现异步事件处理的基本步骤。通过事件机制,可以方便地在应用程序中实现解耦和并发处理
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值