场景:用户注册的时候会发送短信和邮件,注册成功和发送短信、邮件解耦后会提高响应效率
启动类添加注解
@EnableAsync
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
添加异步连接池
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
/**
* 异步调用的线程池配置
*/
@Configuration
public class AsyncConfig {
private static final int MAX_POOL_SIZE = 50;
private static final int CORE_POOL_SIZE = 20;
@Bean("asyncTaskExecutor")
public AsyncTaskExecutor asyncTaskExecutor() {
ThreadPoolTaskExecutor asyncTaskExecutor = new ThreadPoolTaskExecutor();
asyncTaskExecutor.setMaxPoolSize(MAX_POOL_SIZE);
asyncTaskExecutor.setCorePoolSize(CORE_POOL_SIZE);
asyncTaskExecutor.setThreadNamePrefix("async-task-");
asyncTaskExecutor.initialize();
return asyncTaskExecutor;
}
}
创建实体类
public class User {
private int userId;
private String email;
private String msg;
public int getUserId() {
return userId;
}
public String getEmail() {
return email;
}
public String getMsg() {
return msg;
}
public void setUserId(int userId) {
this.userId = userId;
}
public void setEmail(String email) {
this.email = email;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
public class User {
private int userId;
private String email;
private String msg;
public int getUserId() {
return userId;
}
public String getEmail() {
return email;
}
public String getMsg() {
return msg;
}
public void setUserId(int userId) {
this.userId = userId;
}
public void setEmail(String email) {
this.email = email;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
创建用户发布事件
import lombok.Data;
import org.springframework.context.ApplicationEvent;
/**
* 定义第一个事件:用户事件
* 用户注册,注册成功后需要发送邮箱、短信提示用户,并生成工单
*/
@Data
public class UserApplicationEvent extends ApplicationEvent {
private User user;
public UserApplicationEvent(User user) {
super(user);
this.user = user;
}
}
import org.springframework.context.ApplicationEvent;
/**
* 定义第二个事件:用户事件
* 用户注册,注册成功后需要发送邮箱、短信提示用户,并生成工单
*/
public class OrderApplicationEvent extends ApplicationEvent {
private Order order;
public OrderApplicationEvent(Order order) {
super(order);
this.order = order;
}
}
创建事件监听器
import org.springframework.context.event.EventListener;
import org.springframework.core.annotation.Order;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;
import java.util.concurrent.Future;
/**
* 第二种添加监听器的方式:
* 定义一个监听器并注入到容器中,同时指定监听那个事件,监听后执行后续操作
*/
@Component
public class EventApplicationListener {
@EventListener
@Async("asyncTaskExecutor")
@Order(1)//一个事件多个事监听,在同步的情况下,使用@order值越小,执行顺序优先
public void userApplicationEvent(UserApplicationEvent userApplicationEvent) {
System.out.println("发送短信逻辑");
}
@EventListener
@Async("asyncTaskExecutor")
@Order(2)//一个事件多个事监听,在同步的情况下,使用@order值越小,执行顺序优先
public void userApplicationEvent2(UserApplicationEvent userApplicationEvent) {
System.out.println("发送邮件逻辑");
}
@EventListener
@Async("asyncTaskExecutor")
public Future<String> orderApplicationEvent(OrderApplicationEvent orderApplicationEvent) {
System.out.println("其他业务");
return AsyncResult.forValue("返回的值");
}
}
另外一种添加事件监听器方式(不太推荐)
//import org.springframework.context.ApplicationListener;
//import org.springframework.stereotype.Component;
//
///**
// * 第一种添加监听器的方式:
// * 定义一个监听器并注入到容器中,同时指定监听那个事件
// */
//@Component
//public class MyApplicationListener implements ApplicationListener<UserApplicationEvent> {
// @Override
// public void onApplicationEvent(UserApplicationEvent userApplicationEvent) {
// System.out.println("接收到事件");
// }
//}
接下来添加业务逻辑
import com.cmb.config.async.User;
import java.util.concurrent.Future;
public interface UserService {
/**
* 异步调用无返回值
* @param user
*/
void resignUser(User user);
/**
* 异步调用有返回值
* @param str
* @return
*/
Future<String> testAsync2(String str);
}
import com.cmb.config.async.User;
import com.cmb.service.UserService;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;
import java.util.concurrent.Future;
@Service
public class UserServiceImpl implements UserService {
/**
* 显示指定线程池,
*/
@Async(value = "asyncTaskExecutor")
public void resignUser(User user){
System.out.println("注册用户业务逻辑开始执行");
user.setMsg("11");
user.setEmail("11");
user.setUserId(1);
System.out.println("save user");
System.out.println("注册用户业务逻辑结束执行");
return;
}
/**
* 不指定是隐式指定从线程池拿连接
* @param str
* @return
*/
@Async
public Future<String> testAsync2(String str){
//Z注册一个用户。。。
System.out.println("注册用户业务逻辑开始执行");
System.out.println("注册用户业务逻辑结束执行");
String str1 = str + "123";
return AsyncResult.forValue(str1);
}
}
添加接口
@GetMapping("/user/register")
public void testAsync(){
User user = new User();
user.setEmail("123");
user.setMsg("123");
user.setUserId(1);
//用户注册
userServiceImpl.resignUser(user);
System.out.println("完成用户注册。。。");
applicationEventPublisher.publishEvent(new UserApplicationEvent(user));
System.out.println("完成向用户发送短信");
System.out.println("完成向用户发送邮件");
}