【Spring實戰】—— 3 使用facotry-method建立單例Bean總結

若是有這樣的需求spring

  1 不想再bean.xml加載的時候實例化bean,而是想把加載bean.xml與實例化對象分離。安全

  2 實現單例的beanspa

以上的狀況,均可以經過工廠方法factory-method來建立bean線程

這樣再加載bean.xml時,不會直接實例化bean,而是當調用factory-method所指的方法時,纔開始真正的實例化。code

  首先看一下傳統的單例模式的實現方式:orm

  1 最原始的實現單例模式的方法(存在線程不安全):

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

  可是這種方法有一個弊端,就是存在線程的不安全!xml

  好比當兩個線程同時進入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會同步的進行,不會有線程安全問題,可是不單單是實例化,每次調用也須要同步,這樣就會形成不少資源的浪費。blog

  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/beans
    http://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 演出開始...
相關文章
相關標籤/搜索