对于Spring中实现Singleton模式,是以IOC容器为单位,换句话说,一个JVM可能有多个IOC容器,而Java中实现Singleton而言,只有一个JVM。所以说,Spring中实现的Singleton模式与Java中的Singleton设计模式有点不同。
此外,spring singleton的含义是在一个spring 上下文中保持单态。
所以singleton模式中,singleton的class在整个JVM中只有一个instance,Spring的Bean,你可以一个class配置多个Bean,这个class就有了多个instance。这个singleton是指在spring容器中,这个Bean是单实例的,是线程共享的。所以要求这些类都是线程安全的。也就是说,不能出现修改Bean属性的方法,当然除了设值得那些setter。只要满足线程安全,这些bean都可以用singleton。而且我们在绝大多数使用上,也是这样用的,包括dao,service。
Beanfactory是Spring初始以静态方式载入的,Spring的单例IOC是基于容器级的,所以这你都不用担心与考虑.
--应用中对象有两种,行为对象和数据对象,行为对象都要求是线程安全的!也就是允许单例的, 不管是dao 还是 service 对象,都是行为对象,行为对象不应该引用非线程安全的对象做成员量,同时在应用外部的资源(如文件,数据库连接,session)时,要先保证对这些东西的访问是做了并发控制的!
对于spring来讲,<bean scope="singleton"/>或<bean singleton="true"/>都是保证对同一sesionfactory bean是单例的,也就是所谓 sessionfactory 范围的.
--这是一个真实的案例,我们在项目中使用Spring和ACEGI,我之所以选择ACEGI,除了它对权限的良好控制外,
我还看好它的SecurityContextHolder,通过代码来看:
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
<script>render_code();</script>
我可以很容易在系统任意一层得到用户的信息,而不用把用户信息在参数里传来传去,(这也是struts的缺点之一)
但是我在每一次要得到用户信息的时候都写上面的一段代码,未免有些麻烦,所以我在BaseService, BaseDao里都提供了如下方法:
/**
* get current login user info
* @return UserInfo
*/
protected UserInfo getUserInfo()
{
return getUserContext().getUserInfo();
}
/**
* get current login user context
* @return UserContext
*/
protected UserContext getUserContext()
{
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
return (UserContext) auth.getPrincipal();
}
<script>render_code();</script>
这样在其他的Service和Dao类里可以通过
super.getUserContext(), super.getUserInfo()
<script>render_code();</script>
来得到用户的信息,这也为问题的产生提供了温床。请看如下代码:
public class SomeServece extends BaseService implements SomeInterFace
{
private UserInfo user = super.getUserInfo();
public someMethod()
{
int userID = this.user.getUserID();
String userName = this.user.getUserName();
//bla bla do something user userID and userNaem
}
}
<script>render_code();</script>
这段代码在单元测试的时候不会用任何问题,但是在多用户测试的情况下,你会发现任何调用SomeService里someMethod()方法的userID和userName都是同一个人,也就是第一个登陆的人的信息。
其根本原因是Spring的Bean在默认情况下是Singleton的,Bean SomeServece的实例只会生成一份,也就是所SomeServece实例的user对象只会被初始化一次,就是第一次登陆人的信息,以后不会变了。所以BaseService想为开发提供方便,却给开发带来了风险.
正确的用法应该是这样的
public class SomeServece extends BaseService implements SomeInterFace
{
public someMethod()
{
int userID = super.getUserInfo().getUserID();
String userName = super.getUserInfo().getUserName();
//bla bla do something user userID and userNaem
}
}
分享到:
相关推荐
观察者模式 Observer:Swing中的事件模型 工厂模式 Factory:在JDK中遍地都是,比如JDBC、JNDI等,是学习Spring的基础 命令模式 Command:Struts框架的基石 单例模式 Singleton:最简单的设计模式,大量...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.1.1. @Configurable object的单元测试 6.8.1.2. 多application context情况下的处理 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来...
6.8.1. 在Spring中使用AspectJ进行domain object的依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ加载时织入(LTW) 6.9. 更多资源 7...
Spring.NET以Java版的Spring框架为基础,将Spring.Java的核心概念与思想移植到了.NET平台上。 第一章 序言 第二章 简介 2.1.概述 2.2.背景 2.3.模块 2.4.许可证信息 2.5.支持 第三章 背景 3.1.控制反转 第...
将此程序与DataStax DSE Java驱动程序手册中提供的链接一起使用,以初步了解创建程序和设置DSE会话。 背景 在此示例中,DSE会话(您将通过其连接到DSE的对象)已设置为单例类。 在我们的示例程序中, Session类用于...
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中<bean/> 的形式定义。Spring 框架定义的beans都是单件...
总结,我们会选择第一种方式,因为spring的存在就是要消除工厂模式,因为工厂本身就会在每次调用时new出对象,只是把new的工作换了个地方而已。bean作用域singleton prototype;bean作用域request session global...
在这个项目中,我使用注释和Java代码配置创建了Spring项目。 运行应用程序 步骤1.安装Tomcat服务器并将其与IDE连接 第2步。添加lib文件夹中的Jar文件- Right click on Main project -> Properties-> Java Build Path...
6.8.1. 在Spring中使用AspectJ来为domain object进行依赖注入 6.8.2. Spring中其他的AspectJ切面 6.8.3. 使用Spring IoC来配置AspectJ的切面 6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. ...
* * * * Bean的作用域 作用域的种类 Spring 4.3中为Bean的实例定义了7种作用域,如下表所示: 注意:在上表7种作用域中,singleton和prototype是最常用的两种作用域。 在Spring配置文件中,可以使用元素的scope属性...
2. Spring 2.0和 2.5的新特性 2.1. 简介 2.2. 控制反转(IoC)容器 2.2.1. 新的bean作用域 2.2.2. 更简单的XML配置 2.2.3. 可扩展的XML编写 2.2.4. Annotation(注解)驱动配置 2.2.5. 在classpath中自动搜索组件...
弹簧靴中的设计模式 该存储库是一个简单的spring boot应用程序,演示了一些设计模式: 辛格尔顿 控制者 厂 战略 代理 观察者 面向方面的编程 该演示应用程序从2个不同的银行的网站(可以添加更多的银行)中检索...
6.8.4. 在Spring应用中使用AspectJ Load-time weaving(LTW) 6.9. 其它资源 7. Spring AOP APIs 7.1. 简介 7.2. Spring中的切入点API 7.2.1. 概念 7.2.2. 切入点实施 7.2.3. AspectJ切入点表达式 7.2.4. ...
Spring能消除在许多工程中常见的对Singleton的过多使用。根据我的经验,这是一个很大的问题,它降低了系统的可测试性和面向对象的程度。 通过一种在不同应用程序和项目间一致的方法来处理配置文件,Spring能消除...
Spring3.0是Spring在积蓄了3年之久后,隆重推出的一个重大升级版本,进一步加强了Spring作为Java领域第一开源平台的翘楚地位。 Spring3.0引入了众多Java开发者翘首以盼的新功能和新特性,如OXM、校验及格式化框架...
在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类...
单例模式(Singleton) 简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 建造者模式(Builder) 原型模式(Prototype) 结构型 适配器模式(Adapter) 桥接模式...
请叫我大师兄 Java Note ...单例模式(Singleton Pattern) 建造者模式(Builder Pattern) 原型模式(Prototype Pattern) 结构型模式 适配器模式(Adapter Pattern) 桥接模式(Bridge Pattern) 过滤器模式(Fi
java 学习整理文档 Spring框架并没有对单例bean进行任何多线程的封装处理。关于单例bean的线程安全和并发问题需要开发者自行去搞定 最浅显的解决办法就是将多态bean的作用域由“singleton”变更为“prototype”或者...