- 浏览: 1591902 次
- 性别:
- 来自: 吉林
文章分类
- 全部博客 (624)
- C/C++ (33)
- Java (181)
- 网络相关 (7)
- 我爱篮球 (3)
- 也爱足球 (4)
- 杂谈 (1)
- 系统架构 (3)
- Web Service (14)
- Framework (3)
- 系统命令 (8)
- 管理平台相关 (8)
- 其它 (35)
- Websphere (1)
- Struts2 (24)
- Hibernate (16)
- Spring (23)
- javascript (20)
- jquery (23)
- html/css/div (28)
- 数据库 (40)
- JavaWeb (27)
- 设计模式 (2)
- 文档编写 (3)
- SVN (5)
- Ant (1)
- Maven (13)
- 软件项目管理 (8)
- AOP (1)
- kindeditor (1)
- JSON (2)
- Servlt/JSP (4)
- WordXML (2)
- XML (12)
- 面试相关 (7)
- Tomcat (11)
- 性能与调优 (29)
- 职业发展 (2)
- 操作系统 (7)
- AJAX (2)
- DWR (1)
- Eclipse (12)
- 持续集成 (3)
- 批处理命令 (1)
- Mozilla Rhino (2)
- 新鲜技术 (18)
- Apache mina (2)
- 底层技术 (18)
- Linux (22)
- 新鲜技术,IT历史 (1)
- 敏捷开发 (1)
- 版本控制 (5)
- 较火技术 (7)
- 集群 (2)
- Web前端 (13)
- 报表工具 (3)
- 网站架构 (5)
- 大数据 (8)
- 分布式存储 (5)
- 云计算 (8)
- TCP/IP协议 (1)
- 负载均衡 (3)
- 硬件 (1)
- 表现层技术 (3)
- Velocity (3)
- jvm (6)
- 并发编程 (10)
- hadoop (8)
- 数据结构和算法 (12)
- 计算机原理 (1)
- 测试驱动开发-TDD (3)
- 开发技巧 (1)
- 分词器 (1)
- 项目构建工具 (2)
- JMX (4)
- RMI (1)
- 测试技术 (22)
- 网络完全 (1)
- Git (4)
- apache开源包 (4)
- Java常用 (1)
- mock (2)
- OSGi (2)
- MongoDB (1)
- JBPM (1)
- Storm (3)
- mysql (2)
- telnet (1)
- 正则表达式 (1)
- bootstrap (4)
- Apache ActiveMQ (1)
- redis (9)
- Nginx (2)
- rsync+inotify文件同步 (2)
- testng (1)
- 原型设计工具 (1)
- 工程能力 (1)
- 风险控制 (3)
- ibatis (1)
- 分布式 (4)
- 安全技术 (1)
- 计算机基础 (4)
- 消息中间件 (1)
- UML (2)
最新评论
-
u012236967:
java命令执行jar包(里面的main函数)的方式(包括依赖其它的jar包问题) -
世界尽头没有你:
Selenium自动化测试从入门到精通(Java版)百度网盘地 ...
自动化测试工具 Selenium WebDriver 入门教程(针对主流浏览器) -
小小西芹菜:
我喜欢代码简洁易读,服务稳定的推送服务,前段时间研究了一下go ...
dwr实现Reverse Ajax推送技术的三种方式 -
hellozhouqiao:
楼主,请教一点问题.现在我们需要在excel 的页脚里面加上图 ...
FreeMaker + xml 导出word(处理目录,图片和页眉页脚问题) -
乱在长安:
使用Timer会有各种各样的问题好嘛?!书上推荐使用Sched ...
DelayQueue (ScheduledThreadPoolExecutor调度的实现)
单例模式也属于创建型模式,所谓单例,顾名思义,所指的就是单个实例,也就是说要保证一个类仅有一个实例。
单例模式有以下的特点:
①
单例类只能有一个实例
②
单例类必须自己创建自己的唯一实例
③
单例类必须给所有其他对象提供这一实例
下面我们就来写一个简单的单例模式的例子:
Public class Singleton1{
Private static final
Singleton1 instance=new Singleton1();
//私有的默认构造函数
Private
Singleton1(){}
//静态工厂方法
Public static Singleton1 getInstance(){
Return instance;
}
}
大家可以看出来,在这个类被加载时,静态变量instance会被初始化,此时该类的私有构造函数被调用,这时候,单例类的唯一实例就被创建出来了
值得注意的是:由于构造函数是私有的,因此该类不能被继承
还有一种写法也可以实现单例模式:
Public class Singleton2{
Private static final
Singleton2 instance=null;
//私有的默认构造函数
Public
Singleton1(){}
//静态工厂方法
Public synchronized static Singleton2
getInstance(){
If(instance==null){
Instance=new Singleton2();
}
Return instance;
}
}
这种写法和第一种的区别在于:实例并没有直接实例化,而是在静态工厂方法被调用的时候才进行的,而且对静态工厂方法使用了同步化,以处理多线程并发的环境。
这两种写法还有两个非常有意思的名字:第一种称为饿汉式单例,第二种称为懒汉式单例。至于为什么起这个名字,自己好好想想吧。
饿汉式单例在自己被加载时就将自己实例化,如果从资源利用效率角度来讲,比懒汉式单例类稍差些。但是从速度和反应时间角度来讲,则比懒汉式要稍好些。
但是遗憾的是:懒汉式单例类也不能被继承。
我们克服前两种单例类不能被继承的缺点,我们可以使用另外一种特殊化的单例模式,它被称为单例注册表。
Import
java.util.HashMap;
Public class RegSingleton{
Static private HashMap
registry=new HashMap();
//静态块,在类被加载时自动执行
Static{
RegSingleton rs=new RegSingleton();
Registry.put(rs.getClass().getName(),rs);
}
//受保护的默认构造函数,如果为继承关系,则可以调用,克服了单例类不能为继承的缺点
Protected
RegSingleton(){}
//静态工厂方法,返回此类的唯一实例
public static RegSingleton
getInstance(String name){
if(name==null){
name=” RegSingleton”;
}
if(registry.get(name)==null){
try{
registry.put(name,Class.forName(name).newInstance());
}
Catch(Exception
ex){ex.printStackTrace();}
}
Return
(RegSingleton)registry.get(name);
}
}
下面我们来看看Spring中的单例实现,当我们试图从Spring容器中取得某个类的实例时,默认情况下,Spring会才用单例模式进行创建。
<bean
id="date" class="java.util.Date"/>
<bean id="date"
class="java.util.Date" scope="singleton"/> (仅为Spring2.0支持)
<bean
id="date" class="java.util.Date" singleton="true"/>
以上三种创建对象的方式是完全相同的,容器都会向客户返回Date类的单例引用。那么如果我不想使用默认的单例模式,每次请求我都希望获得一个新的对象怎么办呢?很简单,将scope属性值设置为prototype(原型)就可以了
<bean id="date" class="java.util.Date" scope="prototype"/>
通过以上配置信息,Spring就会每次给客户端返回一个新的对象实例。
那么Spring对单例的底层实现,到底是饿汉式单例还是懒汉式单例呢?呵呵,都不是。Spring框架对单例的支持是采用单例注册表的方式进行实现的,源码如下:
public abstract class AbstractBeanFactory implements ConfigurableBeanFactory{
/**
* 充当了Bean实例的缓存,实现方式和单例注册表相同
*/
private final Map singletonCache=new HashMap();
public Object getBean(String name)throws BeansException{
return getBean(name,null,null);
}
...
public Object getBean(String name,Class requiredType,Object[] args)throws BeansException{
//对传入的Bean name稍做处理,防止传入的Bean name名有非法字符(或则做转码)
String beanName=transformedBeanName(name);
Object bean=null;
//手工检测单例注册表
Object sharedInstance=null;
//使用了代码锁定同步块,原理和同步方法相似,但是这种写法效率更高
synchronized(this.singletonCache){
sharedInstance=this.singletonCache.get(beanName);
}
if(sharedInstance!=null){
...
//返回合适的缓存Bean实例
bean=getObjectForSharedInstance(name,sharedInstance);
}else{
...
//取得Bean的定义
RootBeanDefinition mergedBeanDefinition=getMergedBeanDefinition(beanName,false);
...
//根据Bean定义判断,此判断依据通常来自于组件配置文件的单例属性开关
//<bean id="date" class="java.util.Date" scope="singleton"/>
//如果是单例,做如下处理
if(mergedBeanDefinition.isSingleton()){
synchronized(this.singletonCache){
//再次检测单例注册表
sharedInstance=this.singletonCache.get(beanName);
if(sharedInstance==null){
...
try {
//真正创建Bean实例
sharedInstance=createBean(beanName,mergedBeanDefinition,args);
//向单例注册表注册Bean实例
addSingleton(beanName,sharedInstance);
}
catch (Exception ex) {
...
}
finally{
...
}
}
}
bean=getObjectForSharedInstance(name,sharedInstance);
}
//如果是非单例,即prototpye,每次都要新创建一个Bean实例
//<bean id="date" class="java.util.Date" scope="prototype"/>
else{
bean=createBean(beanName,mergedBeanDefinition,args);
}
}
...
return bean;
}
}
以上的源码对于很多同学来说,可能感觉比较恐怖,但是学习要学会抓住要领,刚才的源码中,大家真正要记住的是Spring对bean实例的创建是采用单例注册表的方式进行实现的,而这个注册表的缓存是HashMap对象,如果配置文件中的配置信息不要求使用单例,Spring会采用新建实例的方式返回对象实例
发表评论
-
spring中bean使用parent属性来减少配置
2016-05-30 14:53 2442在基于spring框架开发的项目中,如果有多个bean都是一 ... -
事务相关内容详解(Spring、java)
2016-05-18 14:28 1024Spring的事务传播性与隔离级别 一、事务的四个特 ... -
Spring事务传播机制与隔离级别
2016-05-18 13:47 10326转自:http://blog.csdn.net ... -
使用TransactionTemplate 编程式控制事务
2016-04-25 10:27 3648http://wzhw2008.iteye.com/blog ... -
Spring data redis几种序列化器的比较
2015-03-26 15:23 5545转自:http://stamen.iteye.com/blo ... -
Spring 整合Redis详解(增删改查、PipleLine、测试代码)
2015-03-25 17:11 9026pom构建: [html] view pl ... -
NoSuchMethodError:org.springframework.core.env.ConfigurableEnvironment.merge
2015-03-25 13:26 1607java.lang.NoSuchMethodError: or ... -
Spring propertyplaceholder
2015-03-25 13:23 8041.有些参数在某些阶段中是常量 比如 :a、在开发 ... -
在Spring下集成ActiveMQ
2015-03-12 14:25 793转自:http://www.cnblogs.co ... -
c3p0数据源用户名密码加密或解密(Spring中配置)
2015-01-06 17:22 6351spring2 配置文件 Java代码 ... -
Spring自动扫描装配Bean常用注解
2014-10-12 21:17 68981 引入context命名空间(在Spring的配置文件中) ... -
Spring定时任务
2014-10-03 09:29 731转自:http://gong1208.iteye.com/b ... -
spring框架中多数据源创建加载并且实现动态切换的配置实例代码(转)
2014-05-07 19:40 1613下面是转载的一个Spring动态切换数据源的实现,原网站 ... -
JavaWeb中获得Spring的ApplicationContext
2013-07-04 11:10 569昨天帮同事处理一个网站访问量统计的问题,项目中使用的是SSH ... -
Spring事务传播机制(即事务类型)和隔离级别
2013-06-24 17:52 25961 事务的传播属性(Propagation) 1) REQU ... -
深入理解IOC以及它的优缺点
2013-05-21 10:52 53951. IoC理论的背景我们都知道,在采用面向对象方法设计的 ... -
Spring Framework 开发参考手册
2013-02-26 10:58 1211Spring Framework 开发参考手 ... -
使用SVN检出Struts Spring Hibernate源码
2013-02-05 16:50 1364Spring Spring源码是由springframewo ... -
安装Spring源码工程(转)
2013-02-05 16:49 1502如何安装构建Spring的工 ... -
Spring配置事务的传播行为(PROPAGATION)和隔离级别(Isolation)(终于懂了)
2012-08-01 15:55 2688转载自:http://blog.china ...
相关推荐
《设计模式——Java语言中的应用》是一本专为Java开发者深入理解面向对象设计而编写的经典书籍。设计模式是软件工程领域中经过实践验证的、解决常见问题的有效方案,它们代表了在特定上下文中,针对特定问题的最优...
本篇文章旨在深入探讨Spring框架的设计理念与设计模式,尤其关注其核心组件——`Core`、`Context`和`Beans`的作用与协作方式。 **1. Bean组件** Bean组件是Spring框架的基石,位于`org.springframework.beans`包下...
Spring框架的设计遵循了经典的设计模式,它是一个模块化的架构,允许开发者根据需要选择相应的模块进行项目集成。 使用Spring框架能够为开发者带来许多好处,例如通过依赖注入(Dependency Injection, DI)方法,...
"J2EE项目实训——UML及设计模式课件.rar"这个压缩包文件显然是针对学习J2EE开发和软件设计的学生或专业人士准备的资源。其中包含的两个源码项目——在线商城项目源程序和BBS论坛社区项目源程序,都是典型的J2EE应用...
GoF(Gang of Four)的23种设计模式,如工厂模式、单例模式、观察者模式等,以及Web开发中常见的MVC(Model-View-Controller)模式,都是在框架设计中广泛应用的。这些模式有助于创建松散耦合、高度内聚的系统,从而...
《设计模式与JAVA》这本书是面向Java开发者的一本经典教程,它深入浅出地介绍了软件设计中的重要概念——设计模式。设计模式是经验丰富的软件开发人员在解决常见问题时所形成的可重用解决方案,它们是经过时间考验的...
首先,Spring中广泛运用了两种设计模式:工厂模式和单例模式。工厂模式是一种创建型设计模式,它提供了一种创建对象的最佳方式。在Spring框架中,工厂模式体现在Spring容器(BeanFactory或ApplicationContext)中,...
### Spring 源码分析——设计模式篇 #### 一、引言 Spring框架作为Java企业级开发领域中不可或缺的一部分,其内部集成了多种设计模式,不仅有助于提高系统的可维护性和扩展性,还能够帮助开发者更好地理解和应用...
《设计模式——Java语言版本》这本书深入探讨了如何在Java环境下应用这些模式。 在“设计模式--Java语言版本”中,我们可以期待学习到以下关键知识点: 1. **单例模式**:确保一个类只有一个实例,并提供一个全局...
2. **Java中的设计模式分类**:设计模式通常分为三类——创建型模式(如工厂模式、抽象工厂模式、单例模式、建造者模式和原型模式),结构型模式(如适配器模式、装饰器模式、代理模式、桥接模式、组合模式、外观...
此外,书中可能还会涉及一些最佳实践和设计模式,如单例模式、工厂模式等,以及如何使用JUnit进行单元测试,确保代码质量。对于想要提升Java EE开发能力的程序员来说,这本书无疑是一份宝贵的资源。 总的来说,《轻...
《设计模式——工厂模式》 在软件工程领域,设计模式是一种在特定情境下解决常见问题的模板,它为程序员提供了一种标准的解决方案。工厂模式是面向对象设计中最为人熟知的设计模式之一,属于创建型模式,其主要目标...
在本章中,我们将探讨如何利用两种流行的设计模式——Cairngorm和PureMVC——来构建高效且可扩展的Flex应用程序。这两种模式都是为了帮助开发者在构建复杂的应用程序时避免混乱的代码结构,并确保应用程序能够更好地...
在本课程大作业“软件设计模式与体系结构——服装管理系统”中,我们将深入探讨软件开发中的关键概念,尤其是设计模式和体系结构的应用。这个服装管理系统项目涵盖了多种设计原则和架构模式,旨在帮助学生掌握如何...
【Spring入门笔记】主要介绍了Spring框架的基础知识,包括Spring的核心概念、Bean的配置与作用域、依赖注入、SpringAop和SpringJdbc,以及事务声明。以下是对这些知识点的详细说明: 1. **什么是Spring?** Spring...
1. 设计模式:学习常见的设计模式,如单例、工厂、观察者、装饰器等,提高代码可读性和复用性。 2. SOLID原则:理解SOLID原则,包括单一职责、开闭、里氏替换、接口隔离和依赖倒置,提升代码质量。 3. UML建模:学习...
4. **单例模式**:Spring中的大多数bean默认为单例模式,确保系统中只有一个实例。 5. **策略模式**:例如,Spring的事务管理支持多种策略,如编程式事务管理、声明式事务管理等。 三、源码深度探索 1. **Bean的...
《工厂模式——面向对象设计模式的核心理解》 工厂模式,作为软件工程中最为常见的设计模式之一,是面向对象设计中的重要概念。工厂模式的主要目的是通过引入一个中间的工厂类来负责创建对象,从而将对象的创建过程...