Spring整合Socket@Async在Spring中不生效

今天在做公司项目时,想要使用异步调用去处理方法。于是我把注解@Async 加到了自己一个方法上,后来发现并没有生效。

检查代码:

1.异步连接池

/**

  • @Author wangping
  • @Date 2021-10-28 10:37
  • @Version 1.0
    */
    //线程池
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.task.AsyncTaskExecutor;
    import org.springframework.scheduling.annotation.EnableAsync;
    import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;

@Configuration
@EnableAsync
public class SpringAsyncConfig {

@Bean("taskExecutor")
public Executor asyncServiceExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    // 设置核心线程数
    executor.setCorePoolSize(5);
    // 设置最大线程数
    executor.setMaxPoolSize(20);
    //配置队列大小
    executor.setQueueCapacity(Integer.MAX_VALUE);
    // 设置线程活跃时间(秒)
    executor.setKeepAliveSeconds(60);
    // 设置默认线程名称
    executor.setThreadNamePrefix("调用支付接口");
    // 等待所有任务结束后再关闭线程池
    executor.setWaitForTasksToCompleteOnShutdown(true);
    //执行初始化
    executor.initialize();
    return executor;
}

}2.@SpringBootApplication启动类当中已经添加@EnableAsync注解

3.目标类方法上已经添加@Async(“taskExecutor”)

可能应该是因为aop代理的缘故,被调用方法 和 调用处的代码都处在同一个类,所以只是相当于本类调用,并没有使用代理类 从而@Async并没有产生效果。

于是单独创建一个类调用@Async处理的方法,还是不行

@Async注解的实现都是基于Spring的AOP,后面创建的类也必须用spring管理

总结:

失效原因
1.@SpringBootApplication启动类当中没有添加@EnableAsync注解。
2.异步方法使用注解@Async的返回值只能为void或者Future。
3.没有走Spring的代理类。因为@Transactional和@Async注解的实现都是基于Spring的AOP,而AOP的实现是基于动态代理模式实现的。那么注解失效的原因就很明显了,有可能因为调用方法的是对象本身而不是代理对象,因为没有经过Spring容器管理。

解决方法:
这里具体说一下第三种情况的解决方法。
1.注解的方法必须是public方法。
2.方法一定要从另一个类中调用,也就是从类的外部调用,类的内部调用是无效的。
3.如果需要从类的内部调用,需要先获取其代理类。
创建spring转换类(转换的类一定是接口类)
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**

  • @Author wangping

  • @Date 2021-10-11 16:21

  • @Version 1.0
    */
    //整合Socket
    @Component
    public class SpringUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    if(SpringUtil.applicationContext == null) {
    SpringUtil.applicationContext = applicationContext;
    }
    }

    //获取applicationContext
    public static ApplicationContext getApplicationContext() {
    return applicationContext;
    }

    //通过name获取 Bean.
    public static Object getBean(String name){
    return getApplicationContext().getBean(name);
    }

    //通过class获取Bean.
    public static T getBean(Class clazz){
    return getApplicationContext().getBean(clazz);
    }

    //通过name,以及Clazz返回指定的Bean
    public static T getBean(String name,Class clazz){
    return getApplicationContext().getBean(name, clazz);
    }
    }
    创建接口类

public interface SocketService {

public void onlineAndnoplatePay(JSONObject json, OutputStream out);

}
实现类

import com.alibaba.fastjson.JSONObject;
import com.lianfu.smartparking.controller.ThreadServerSocket;
import com.lianfu.smartparking.netty.SocketController;
import com.lianfu.smartparking.service.SocketService;
import com.lianfu.smartparking.utils.AmountUtils;
import com.lianfu.smartparking.utils.SpringUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.servlet.ServletContext;
import java.io.IOException;
import java.io.OutputStream;
import java.util.UUID;

/**

  • @Author wangping
  • @Date 2021-11-11 14:12
  • @Version 1.0
    */

@Service
public class SocketServiceImpl implements SocketService {

@Autowired
private ServletContext servletContext;

private final Logger logger = LoggerFactory.getLogger(ThreadServerSocket.class);

@Async("taskExecutor")
@Override
public void onlineAndnoplatePay(JSONObject json, OutputStream out) {

}

调用
private SocketService socketService=SpringUtil.getBean(SocketService.class);

socketService.onlineAndnoplatePay(json, out);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值