springbank 开发日志 一次因为多线程问题导致的applicationContext.getBean()阻塞
几天前遇到的这个问题。由于交易是配置的,不同的交易是同一个类的不同实例,所以不可能提前将其以@autowired类似的方式注入到需要的类中
<op:transaction id="Recharge" template="TransTemplate"></op:transaction>
<op:transaction id="QueryAgreementAcct" template="TransTemplate"></op:transaction>
只能写一个工具类,实现ApplicationContextAware,取得容器,然后收到交易报文的时候,根据报文里的交易名,去取得容器中对应的transaction bean。然后根据bean的template等等信息,往下执行。
但是当我在做这件事情的时候,遇到一个奇怪的问题。这个问题我在cnblog上问过(https://q.cnblogs.com/q/95168/)。问了之后这段时间在准备一场面试,唉唉,失败了。所以今天才回过头来看这个问题:
public class TcpServer implements ApplicationContextAware{
private OpenbankExecutor executor;
private int port;
private PacketHandler packetHandler;
private ServerSocket serverSocket;
private Socket socket;
private ApplicationContext applicationContext;
private final Logger log = LoggerFactory.getLogger(getClass());
public void init() throws IOException {
serverSocket = new ServerSocket(port);
log.debug("TcpServer 成功启动");
while(true) {
socket = serverSocket.accept();
System.out.println("收到socket请求");
executor.execute(new Runnable() {
@Override
public void run() {
try {
Map context = packetHandler.handle(socket.getInputStream());
String tranCode = (String) context.get("tranCode");
Assert.hasText(tranCode);
Transaction transaction = (Transaction) applicationContext.getBean(tranCode);
Template template = (Template) applicationContext.getBean(transaction.getTemplate());
log.debug("transaction: "+transaction.getId());
log.debug("transaction: "+template.getId());
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
这个TcpServer 类也是Spring容器管理的:
<bean id="tcpServer" class="com.openbank.portal.server.TcpServer" init-method="init">
<property name="executor" ref="openbankThreadPool"/>
<property name="port" value="${tcp.port}"/>
<property name="packetHandler" ref="xmlpacketHandler"/>
</bean>
结果我测了一下,收到交易报文之后,走到上面代码红色的地方就“卡”住了。就像程序执行完了一样,但是没有打印出后面的debug信息,纠结了一段时间没有搞懂为什么。
今天我把spring的源代码下载下来了,DEBUG了一下,发现好像是锁的问题,因为走到了一个synchronized方法就没有后文了,可见是一直没有获取到锁
然后我又写了一些测试,把Spring启动期间所有被实例化的Singleton全部打印出来看,最后才慢慢搞明白
原来就是线程的问题。
因为啊因为啊,我上面代码里面可以看到,socket = serverSocket.accept();
这一段,是直接在TcpServer被初始化时就要运行的,但是这里阻塞的,一直等待报文的到来。就是这样,导致spring加载bean的过程,加载到这个bean也就卡住了,甚至后面还有bean根本没有机会得到实例化。
解决方式很简单,我把socket = serverSocket.accept(); 这个放到一个新开的线程里面取处理就好了。
springbank 开发日志 一次因为多线程问题导致的applicationContext.getBean()阻塞的更多相关文章
- SpringBank 开发日志 使用maven构建dubbo服务的可执行jar包
写这篇日志的时候,我已经完成了这个目标,并且中间经历了一次面试.现在回过头看,已经觉得印象不那么深刻了,果然还是一边思考,一边记录这样最好.但我还是严格要求自己,从新做了梳理,对相关配置进行了整理和说 ...
- SpringBank 开发日志 Mybatis 使用redis 作为二级缓存时,无法通过cacheEnabled=false 将其关闭
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC ...
- SpringBank 开发日志 一种简单的拦截器设计实现
当交易由Action进入Service之前,需要根据不同的Service实际负责业务的不同,真正执行Service的业务逻辑之前,做一些检查工作.这样的拦截器应该是基于配置的,与Service关联起来 ...
- springbank 开发日志 springbank是如何注册handler的
这要从DefaultAnnotationHandlerMapping这个类说起,该类被@Component注释,该类被Spring IOC容器实例化之后,将会执行其initApplicationCon ...
- springbank 开发日志 Spring启动过程中对自定义标签的处理
这篇随笔的许多知识来源于:http://www.importnew.com/19391.html 之所以会去看这些东东,主要是希望能够模仿spring mvc的处理流程,做出一套合理的交易处理流程. ...
- SpringBank 开发日志 重新设计Action调用Service的参数传递 使用泛型解决类型转换问题
之前想的比较简单,请求到达controller的时候,传给action的参数没有经过任何封装,就是一个Map.然后action再调用service的时候,传递的参数也是map @Controller ...
- springbank 开发日志 springbank是如何执行一个handler的requestMapping对应的方法的
占位 从dispatcher说起,方法doDispatch(Map request)的参数request是一个通过解析来报报文新城的map //获取HandlerExecutionChain,其中封装 ...
- springbank 开发日志 SpringMVC是如何找到handler找到对应的方法并执行的
从DispatcherServlet说起,本文讨论的内容都是DispatcherServlet的doDispatch方法完成 mappedHandler是一个HandlerExecutionChain ...
- springbank 开发日志 阅读spring mvc的源代码真是受益良多
决定模仿spring mvc的dispatcher->handlerMapping(return executorChain)->handler.execute 这样的流程之后,就开始看s ...
随机推荐
- WebLogic 中的基本概念【转】
完全引用自: WebLogic 中的基本概念 WebLogic 中的基本概念 上周参加了单位组织的WebLogic培训,为了便于自己记忆,培训后,整理梳理了一些WebLogic的资料,会陆续的发出来, ...
- Neural Networks and Deep Learning(week4)Building your Deep Neural Network: Step by Step
Building your Deep Neural Network: Step by Step 你将使用下面函数来构建一个深层神经网络来实现图像分类. 使用像relu这的非线性单元来改进你的模型 构建 ...
- HTML5视频播放插件Video.js使用详解
一.Video.js简介 Video.js 是一个开源的 Html5 jquery 视频插件,这个插件可以用来处理 Flash 视频,它还是一个多平台支持的产品. Moreover,YouTube,V ...
- 由-webkit-transform-style:preserve-3d;所想
看一个用css3写幻灯片的demo用到了这么几个属性 .demo{ -webkit-transform-style:preserve-3d; -webkit-perspective:800px; -w ...
- Java开发中各种集合框架简介
在大数据MapReduce作业开发中,我们经常会遇到一些大小表的join,这是如果这个小表足够“小”的话,我们可以使用进行“map-join-side”,这要就可以有效的降低reduce端的压力,但是 ...
- pythonic语法
b="$".join(str(x) for x in range(10)) a= 2 if 5<2 else 3 print (a)#a是3
- 前端 - js方式Ajax/ jquery方式Ajax / 伪 ajax /伪ajax 进阶方式
DJANGO环境搭建: 目录文件: 关闭CSRF 添加目录文件路径 配置url 视图配置: index页面配置: 测试:(成功) 进入正题: ajax 通过GET提交数据至后台: <!DOCTY ...
- Shiro简介及入门(四)
1.1 什么是shiro shiro是apache的一个开源框架,是一个权限管理的框架,实现 用户认证.用户授权. spring中有spring security (原名Acegi),是一个权 ...
- np.savetxt()——将array保存到txt文件,并保持原格式
问题:1.如何将array保存到txt文件中?2.如何将存到txt文件中的数据读出为ndarray类型? 需求:科学计算中,往往需要将运算结果(array类型)保存到本地,以便进行后续的数据分析. 解 ...
- 【逆向工具】IDA使用3-全局变量、数组、结构体
全局变量 测试代码 全局变量既可以是某对象函数创建,也可以是在本程序任何地方创建.全局变量是可以被本程序所有对象或函数引用.下面这段代码中将int.float.char变量定义在main函数之外. / ...