2019独角兽企业重金招聘Python工程师标准>>>

如果有这样的需求

  1 不想再bean.xml加载的时候实例化bean,而是想把加载bean.xml与实例化对象分离。

  2 实现单例的bean

以上的情况,都可以通过工厂方法factory-method来创建bean

这样再加载bean.xml时,不会直接实例化bean,而是当调用factory-method所指的方法时,才开始真正的实例化。

  首先看一下传统的单例模式的实现方式:

  1 最原始的实现单例模式的方法(存在线程不安全):

public class SingletonOne {private static SingletonOne instance = null;private SingletonOne() {}public static SingletonOne getInstance() {if (instance == null) {instance = new SingletonOne(); }return instance;}
}    

  但是这种方法有一个弊端,就是存在线程的不安全!

  比如当两个线程同时进入if(instance == null)时,一个线程判断了当前为空,然后切换到另一个线程,这个线程也判断为空。然后切换回第一个线程,进行实例化,再切换到第二个线程,进行实例化。这样就存在了两个实例。

  2 通过关键字Synchronized强制线程同步 

package com.something.singleton;
public class SingletonTwo {private static SingletonTwo instance = null;private SingletonTwo() {}public static synchronized SingletonTwo getInstance() {if (instance == null) {instance = new SingletonTwo();}return instance;}
}

  这样当线程进行到getInstance会同步的进行,不会有线程安全问题,但是不仅仅是实例化,每次调用也需要同步,这样就会造成很多资源的浪费。

  3 通过静态内部类进行单例

public class SingletonThree {private static class SingletonHolder{static SingletonThree instance = new SingletonThree();}  private SingletonThree() {}public static SingletonThree getInstance() {return SingletonHolder.instance;}
}

  这种方法时最推荐的一种方法,由于Java的调用机制,SingletonHolder只有在调用getInstance的时候才会加载,而内部的静态类只会被加载一次,因此又是线程安全的。

  总结起来

  第一种方法,是存在线程安全问题的。

  第二种方法,则消耗了一定的资源。

  第三种方法,比较推荐。

  下面通过spring的factory-method来创建单例的bean

  首先通过静态内部类创建一个单例对象

package com.spring.test.factorymethod;public class Stage {public void perform(){System.out.println("演出开始...");}private Stage(){}private static class StageSingletonHolder{static Stage instance = new Stage();}public static Stage getInstance(){return StageSingletonHolder.instance;}
}

  在spring配置文件中指定加载的方法getInstance

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.springframework.org/schema/beans"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd"><bean id="theStage" class="com.spring.test.factorymethod.Stage"factory-method="getInstance"></bean>
</beans>

  通过应用上下文调用bean获取实例

package com.spring.test.factorymethod;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class test {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");Stage stage = ((Stage)ctx.getBean("theStage")).getInstance();stage.perform();}
}

  执行结果

一月 24, 2015 6:38:18 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@512dbd1a: startup date [Sat Jan 24 18:38:18 CST 2015]; root of context hierarchy
一月 24, 2015 6:38:19 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [bean.xml]
一月 24, 2015 6:38:19 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@2d1879ea: defining beans [duke,sonnet29,poeticDuke,theStage]; root of factory hierarchy
演出开始...

转载于:https://my.oschina.net/u/204616/blog/545265

【Spring实战】—— 3 使用facotry-method创建单例Bean总结相关推荐

  1. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  2. Spring IOC 容器源码分析 - 获取单例 bean

    1. 简介 为了写 Spring IOC 容器源码分析系列的文章,我特地写了一篇 Spring IOC 容器的导读文章.在导读一文中,我介绍了 Spring 的一些特性以及阅读 Spring 源码的一 ...

  3. Spring源码 - 从缓存中获取单例Bean

    # Spring源码 - 从缓存中获取单例Bean Spring版本:Spring 5.3.13-release # 1.从缓存中获取单例Bean 单实例Bean在Spring的同一个容器中只会创建一 ...

  4. 头条一面:Spring IOC容器中只存放单例Bean吗?

    最近,很多小伙伴出去面试,感觉自己面的不是很理想,回来后,不少小伙伴把面试题做了记录发给我,让我给大家解析下,然后发出来.当我看到这些面试题时,快速在脑海中构建起了整个知识体系,从基础到框架.从分布式 ...

  5. 单元测试 applicationinfomanager bean无法注入_你真的会用Spring吗?如何在单例Bean中注入原型Bean...

    遇到什么问题 假设单例 BeanA 需要使用原型 BeanB(BeanB 可能是 BeanA 的一个属性值).可是容器仅创建一次单例 BeanA,因此只有一次机会来设置属性 BeanB. @Scope ...

  6. 在Python中创建单例

    这个问题不是为了讨论是否需要单例设计模式 ,是否是反模式,还是针对任何宗教战争,而是要讨论如何以最pythonic的方式在Python中最好地实现此模式. 在这种情况下,我定义"最pytho ...

  7. Spring单例Bean与单例模式的区别

    Spring单例Bean与单例模式的区别在于它们关联的环境不一样,单例模式是指在一个JVM进程中仅有一个实例,而Spring单例是指一个Spring Bean容器(ApplicationContext ...

  8. 在spring中,prototype scoped bean 如何注入单例bean中

    2019独角兽企业重金招聘Python工程师标准>>> 参考博文:http://www.javacodegeeks.com/2012/08/spring-scoped-proxy.h ...

  9. IOS基础学习日志(七)利用dispatch_once创建单例及使用

    自苹果引入了Grand Central Dispatch (GCD)(Mac OS 10.6和iOS4.0)后,创建单例又有了新的方法,那就是使用dispatch_once函数,当然,随着演进的进行. ...

最新文章

  1. paddle一体安装
  2. JQuery Deferred 对象
  3. 分类器评价与在R中的实现:ROC图与AUC
  4. 深度解析:服务器架构和技术变革
  5. 干货下载 | 高效金融客户分析体系如何搭建?
  6. LODOP打印table表格宽度固定-超宽隐藏
  7. 替代触发器如何加判断 条件_《小逻辑》:如何设定目标,制定计划,做出更好的选择...
  8. status_code想要得到302却得到200_中考200天倒计时!教你高效规划!抓紧抢报预留座位!...
  9. LeetCode 第 33 场双周赛(511/3304,前15.5%,第4次全部通过)
  10. 小汤学编程之MySQL(三)——约束、多表查询、事务和数据库其他操作
  11. 【Elasticsearch】elasticsearch 7.x 查看分片未分配 (UNASSIGNED) 的原因
  12. 一次Python性能调优经历
  13. 简记Inception系列
  14. spring security 使用 application/json 接收数据
  15. 阿里巴巴 Java开发手册 最新官网下载
  16. MatrixOne混沌测试之道
  17. window8系统 dns有问题怎么修复,浏览器代理设置,浏览器提示网页无法显示
  18. 一款表达谱数据分析的神器--CCLE--转载
  19. 操作系统中文件存储空间的管理
  20. java工单系统源码_基于jsp的工单管理系统-JavaEE实现工单管理系统 - java项目源码...

热门文章

  1. FBL3N/FBL3H/FAGLL03/FAGLL03H的区别
  2. 如何通过交货单把B库存发出
  3. 业内公认的AI发展最大挑战,有哪些技术突破机会?
  4. 浅谈机器学习在市场营销中的应用
  5. SAP WM 业务部门Unplanned工单消耗导致WM层面单据异常问题之分析
  6. 通过例子10分钟快速看懂pad_sequence、pack_padded_sequence以及pad_packed_sequence
  7. (完全解决)(numba)TypingError: Failed in nopython mode pipeline( Invalid use of Function)
  8. 骆利群院士最新Science综述:神经环路架构,激发新的AI
  9. 重磅,2020年度第十届吴文俊人工智能科学技术奖获奖名单公示
  10. CICC科普栏目|颠覆认知!看完这些图,你的世界观还好吗?