`

设计模式在实际开发中的使用——单例模式

 
阅读更多

单例模式:确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。

 

  • Runtime类

Runtime是个单例类,表示当前JVM的运行环境。

可以看如下测试代码

Runtime runtime1 = Runtime.getRuntime();
Runtime runtime2 = Runtime.getRuntime();
System.out.println(runtime1.equals(runtime2));

返回true,两个Runtime的实例是一个对象。所以要用Runtime的对象时,不用像上面代码定义一个Runtime runtime1对象,而是直接Runtime.getRuntime()拿来用。不管调用几次都是返回同一个实例。

 

  • Spring中的单例

如果在JVM中定义的单例类,可能由于长时间不用而被JVM自动回收。Spring的IOC容器里面定义的bean默认是单例,并且整个生命周期是Spring在管理,不会被JVM自动回收。

例如如下定义的service类

<bean id="helloWorldService" class="com.spring.HelloWorldService"/>

在J2EE工程里面,service和dao层都交给Spring管理,并且都是单例实现,每次拿到的service和到对象都是同一个对象。

 

  • 不适合使用单例的场景

前面说到service和dao层都是单例的,可是action呢。strusts2的action里面有成员变量,对应form表单提交的数据,所以struts2的action一定不能是单例,每次请求进的action都是不同的实例,否则在高并发下成员变量的值就会混乱。

假如将struts2的action交给spring管理,一定要加上@Scope("prototype")注释,该action不是一个单例。

@Controller
@Scope("prototype")
public class LoginAction extends BaseAction {

	@Resource
	private ILoginService loginService;

	private String userName; 
	private String passWord; 
}

 

同样的道理,Servlet在web容器中只被初始化一次,是个单例类,也就是所说的线程不安全。所以Servlet里面是没有成员变量的。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics