`

[Spring]并发访问bean出错解决方案,Spring中Bean的生命周期。

阅读更多

项目准备交付了,却出现了一个致命的问题:

 

项目场景:有一个核心业务类--根据个人编号,调用各种数据进行运算。

 

出现问题:A用户和B用户同时访问出现乱码错误,并且偶尔出现,A提出请求的时候返回B的结果。

 

重现错误:因为没有测试用例,项目几乎裸奔。所以用js模拟用户频繁请求,一下是html测试代码:

 

<html>
<head><title> New Document </title>
</head>
<body>
<form id="form1" name="form1" method="post" action="PreCompe.action">
        <label>个人编号:
          <input name="perscode" type="text" id="perscode"  value="" size="50"  style="height:25px; width:250px"/>
        </label>
</form>
<form action="#" id="form2" name="form2">
<input type="button" value="开始" name="btnStart"/>
<input type="button" value="重置" name="btnReset"/>
<input name="txt1" type="text" value="0" size="12"/>
</form>
</body>
</html>
<script language="JavaScript" type="text/javascript">
<!--
//获取表单中的表单域
var txt=document.form2.elements["txt1"];
var btnStart=document.form2.elements["btnStart"];
var btnReset=document.form2.elements["btnReset"]
//定义定时器的id
var id;
//每10毫秒该值增加1
var seed=0; 
btnStart.onclick=function(){
      //根据按钮文本来判断当前操作
      if(this.value=="开始"){
              //使按钮文本变为停止
              this.value="停止";
              //使重置按钮不可用
              btnReset.disabled=true;
              //设置定时器,每0.01s跳一次
              id=window.setInterval(tip,10);
      }else{
              //使按钮文本变为开始
              this.value="开始";
              //使重置按钮可用
              btnReset.disabled=false;
              //取消定时
              window.clearInterval(id);
      }
}

//重置按钮
btnReset.onclick=function(){
     seed=0;
}
//让秒表跳一格
function tip(){
      seed++;
      txt.value=seed/100;
	  openWin(seed);
}
//-->
function openWin(number){
	var perscode = document.form1.perscode.value;
       window.open ("PreCompe.action?&compeopera=1&treattype=2&perscode="+perscode,"newwindow"+number,"height=600,width=800,top=400,left=400,toolbar=no,menubar=no,scrollbars=no, resizable=no,location=no, status=no");
}
</script>

 

原理很简单,测试用例复杂,所以干脆就直接模拟很多用户每一秒钟请求一次,肯定会有并发发生。然后是多台机器同时访问。

 

结果:控制台显示,一个业务类实例没有完成,另外一个实例已经开始。

 

BUG分析:业务类一开始实例化后,存在于内存,多个请求调用产生交叉。

 

解决方法:

 

<bean id="builder" class="com.medical.domain.medcompe.impl.ConcreateBuilder" singleton="false">

 

 

附上引自:http://blog.163.com/tangyang_personal/blog/static/46229613200832235353419/的一个教程。

 

Spring中Bean的生命周期 在spring中,从BeanFactory或ApplicationContext取得的实例为Singleton,也就是预设为每一个Bean的别名只能维持一个实例,而不是每次都产生
一个新的对象
使用Singleton模式产生单一实例,对单线程的程序说并不会有什么问题,但对于多线程的程序,就必须注意安全(Thread-safe)的议题,防止多个线程
同时存取共享资源所引发的数据不同步问题。
然而在spring中 可以设定每次从BeanFactory或ApplicationContext指定别名并取得Bean时都产生一个新的实例:例如:
<bean singleton="false">
在spring中,singleton属性默认是true,只有设定为false,则每次指定别名取得的Bean时都会产生一个新的实例
一个Bean从创建到销毁,如果是用BeanFactory来生成,管理Bean的话,会经历几个执行阶段:
    1:Bean的建立:
          有BeanFactory读取Bean定义文件,并生成各个Bean实例
    2:属性注入:
          执行相关的Bean属性依赖注入
    3:BeanNameAware的setBeanName():
          如果Bean类有实现org.springframework.beans.BeanNameAware接口,则执行它的setBeanName()方法
    4:BeanFactoryAware的setBeanFactory():
          如果Bean类有实现org.springframework.beans.factory.BeanFactoryAware接口,则执行它的setBeanFactory()方法
    5:BeanPostProcessors的ProcessBeforeInitialization()
          如果任何的org.springframework.beans.factory.config.BeanPostProcessors实例与Bean实例相关。则执行BeanPostProcessors实例
          的processBeforeInitialization()方法
    6:initializingBean的afterPropertiesSet():
          如果Bean类已实现org.springframework.beans.factory.InitializingBean接口,则执行他的afterProPertiesSet()方法
    7:Bean定义文件中定义init-method:
          可以在Bean定义文件中使用"init-method"属性设定方法名称例如:
          <bean calss="onlyfun.caterpillar.HelloBean" init-method="initBean">
          如果有以上设置的话,则执行到这个阶段,就会执行initBean()方法
    8:BeanPostProcessors的ProcessaAfterInitialization()
          如果有任何的BeanPostProcessors实例与Bean实例关联,则执行BeanPostProcessors实例的ProcessaAfterInitialization()方法
    9:DisposableBean的destroy()
          在容器关闭时,如果Bean类有实现org.springframework.beans.factory.DisposableBean接口,则执行他的destroy()方法
    10:Bean定义文件中定义destroy-method
          在容器关闭时,可以在Bean定义文件中使用"destroy-method"属性设定方法名称,例如:
          <bean destroy-method="destroyBean">
          如果有以上设定的话,则进行至这个阶段时,就会执行destroyBean()方法,如果是使用ApplicationContext来生成并管理Bean的话
          则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean
          类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行
          BeanPostProcessors的ProcessBeforeInitialization()及之后的流程

0
0
分享到:
评论
1 楼 litianyu0815 2011-09-15  
唉 看不懂啊

相关推荐

    Spring.3.x企业应用开发实战(完整版).part2

    3.5.2 ApplicationContext中Bean的生命周期 3.6 小结 第4章 在IoC容器中装配Bean 4.1 Spring配置概述 4.1.1 Spring容器高层视图 4.1.2 基于XML的配置 4.2 Bean基本配置 4.2.1 装配一个Bean 4.2.2 Bean的命名 4.3 ...

    Spring3.x企业应用开发实战(完整版) part1

    3.5.2 ApplicationContext中Bean的生命周期 3.6 小结 第4章 在IoC容器中装配Bean 4.1 Spring配置概述 4.1.1 Spring容器高层视图 4.1.2 基于XML的配置 4.2 Bean基本配置 4.2.1 装配一个Bean 4.2.2 Bean的命名 4.3 ...

    2024年Java高工面试题 2024年Java高工面试题 2024年Java高工面试题

    2024年Java高工面试题 ...(3)利用Bean definition创建Bean就是Bean的创建生命周期,包括:合并Bean Definition 推断构造方法、实例化、属性填充、初始化前、初始化、初始化后等其中AOP就是发生在初始化后这一步

    【大厂面试题】SSM框架面试题合集及其答案

    谈谈Springbean的生命周期,作用域 Mybatis中Dao接口的工作原理 SpringlOC和SpringAOP的实现原理(源码主线流程) Spring的并发问题-有状态Bean和无状态Beanmd Spring中的循环依赖解决详解 springmvc和mybatis的工作...

    【大厂面试题】SSM框架面试题合集及其答案Java面试题专题之SSH框架-ssm框架面试题

    1、谈谈Springbean的生命周期,作用域 2、Mybatis中Dao接口的工作原理 3、SpringlOC和SpringAOP的实现原理(源码主线流程) 4、Spring的并发问题-有状态Bean和无状态Beanmd Spring中的循环依赖解决详解 4、springmvc和...

    JAVA面试常见问题整理

    同时,还讲解了一些关于多线程编程的知识,如线程的生命周期、状态、以及线程安全等问题。 在Java集合框架方面,文章介绍了List、Set和Map的区别和特点,以及它们的使用场景。接下来,文章重点讲解了...

    Java Web程序设计教程

    3.3.3servlet的生命周期 49 3.3.4load-on-startupservlet 50 3.4自定义标签库 51 3.5预处理用户请求:filter 53 3.6使用listener 56 3.7项目实战——用户登录 59 本章小结 62 课后练习 63 第4章sql与jdbc ...

    经典JAVA.EE企业应用实战.基于WEBLOGIC_JBOSS的JSF_EJB3_JPA整合开发.pdf

    8.6.1 无状态Session Bean的生命周期 321 8.6.2 有状态Session Bean的生命周期 322 8.6.3 定制Session Bean的生命 周期行为 323 8.7 在Session Bean中使用事务 327 8.7.1 容器管理事务 327 8.7.2 Bean管理事务 330 ...

    低清版 大型门户网站是这样炼成的.pdf

    6.2.4 bean的作用域与生命周期 374 6.2.5 基于xml方式的bean装配 376 6.2.6 基于annotation方式的bean装配 381 6.2.7 基于xml方式的aop实现 386 6.2.8 基于annotation方式的aop实现 391 6.3 spring 2.5事务管理...

    java面试题

    并发问题解决方案 59 71.7. Hibernate是如何延迟加载? 60 71.8. Hibernate中怎样实现类之间的关系?(如:一对多、多对多的关系) 60 71.9. 说下Hibernate的缓存机制 60 71.10. Hibernate的查询方式 60 71.11. 如何...

    word源码java-java-knowledge-collection:Java核心知识点梳理

    生命周期 Kafka ... 设计模式 创建型 单例模式(Singleton) 简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 建造者模式(Builder) 原型模式(Prototype) 结构...

    从J2SE到J2EE知识点介绍

    3. 生命周期及状态转换 84 4. 线程调度 85 5. 线程同步 92 三. Jsp 101 (一) myeclipse上配置Tomcat服务器 101 (二) Jsp+servlet+bean版HelloWorld概览 105 (三) Jsp基本页面标签 116 1. 标签 116 2. contentType...

    java8stream源码-JPP:JPP

    java8 stream 源码 JPP JPP - Java Promotion Process 是一个Java能力提升的计划,与君共勉 ...你可以记录有趣的案例Demo 你可以链接有深度的博客文章 ...更新2021-1-27:补充生命周期AOP处理 及 singletonFactories 说明

    JBoss Seam 工作原理、seam和hibernate的范例、RESTFul的seam、seam-gen起步、seam组件、配置组件、jsf,jboss、标签、PDF、注解等等

    1.3. Seam 中的可点击列表:消息示例............................................................................................................................. 27 1.3.1. 理解代码.........................

    JAVA核心知识点整理(有效)

    1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ........................

Global site tag (gtag.js) - Google Analytics