您好,欢迎来到五一七教育网。
搜索
您的当前位置:首页Spring AOP异步操作实现

Spring AOP异步操作实现

来源:五一七教育网

1.异步场景分析

​ 在开发系统的过程中,通常会考虑到系统的性能问题,提升系统性能的一个重要思想就是"串行" 改 "并行"。说起"并行"自然离不开"异步",今天我们就来聊聊如何使用Spring的@Async的异步注解。

1.2 Spring 业务的异步实现

1.2.1 启动异步配置

​ 基于注解方式的配置中,借助@EnableAsync注解进行异步启动声明,SpringBoot版的项目中,将此注解应用到启动类上,代码示例如下:

@EnableAsync //Spring容器启动时会创建线程池
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
1.2.2 Spring中@Async注解应用

在需要异步执行的业务方法上,使用@Async方法进行异步声明。

/**
  * @Async描述的方法为一个异步切入点方法,
  * 此方法会在spring提供的线程池中的线程上去运行
  */
@Async
@Transactional(propagation = Propagation.REQUIRES_NEW)
@Override
public void insert(Log log) {
    System.out.println(Thread.currentThread().getName()+"-->LogServiceImpl.insert");
    try{Thread.sleep(5000);}catch (Exception e){}//模拟耗时操作
    System.out.println(log);
    logMapper.insert(log);
}

当我们需要自己对Spring框架提供的线程池进行一些简易配置,可以参考如下代码:

spring:
  task:
    execution:
      pool:
        queue-capacity: 128
        core-size: 5
        max-size: 128
        keep-alive: 60000
      thread-name-prefix: db-service-task-

其中:

1.2.3 Spring 自定义异步池的实现

​ 对于@Async注解默认会基于 ThreadPoolTaskExecutor 对象获取工作线程,然后调用由 @Async 描述的方法,让方法运行于另一个工作线程,以实现异步操作。

​ 但是假如系统中的默认拒绝处理策略以及任务执行过程的异常处理不能满足自身业务需求的话 , 可以对异步线程池进行自定义操作 , 线程池优化设计如下 :

@Slf4j
@Setter
@Configuration //此注解描述的类为一个配置类,需要交给Spring管理
//读取Spring配置文件中以spring.async.task为前缀的数据,并通过set方法注入给属性
@ConfigurationProperties("spring.async.task")
public class SpringAsyncConfig implements AsyncConfigurer {
	private int corePoolSize = 5;
	private int maxPoolSize = 100;
	private int keepAliveSeconds = 60;
	private int queueCapacity=  128;
	private String threadNamePrefix = "tast===>";
	@Override
	public Executor getAsyncExecutor() {
		System.out.println("corePoolSize="+corePoolSize);
		ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
		executor.setCorePoolSize(corePoolSize);
		executor.setMaxPoolSize(maxPoolSize);
		executor.setKeepAliveSeconds(keepAliveSeconds);
		executor.setQueueCapacity(queueCapacity);
		executor.setThreadNamePrefix(threadNamePrefix);
		//自定义拒绝处理策略
		executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
			@Override
			public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
				log.error("队列已满并且已无线程可用");
			}
		});
		executor.initialize();
		return executor;
	}
    
    //当执行有异常时
	@Override
	public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
		return new AsyncUncaughtExceptionHandler() {
			@Override
			public void handleUncaughtException(Throwable ex, Method method, Object... params) {
				log.error("任务执行时出现了 {}",ex.getMessage());
			}
		};
	}
}

application.yml 配置文件中连接池的自定义配置如下 :

spring:
	async:
   		task:
      		corePoolSize: 10
      		maxPoolSize: 20
      		keepAliveSeconds: 50
      		queueCapacity: 128
      		threadNamePrefix: db-async-service-task-

后续在业务类中,假如我们使用@Async注解描述业务方法,默认会使用ThreadPoolTaskExecutor池对象中的线程执行异步任务。

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 517ttc.cn 版权所有 赣ICP备2024042791号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务