2014-10-28 40 views
4

Spring將bean作用域提供爲「原型」。意味着當應用程序需要bean時,Spring容器將創建一個新的/新的bean實例。 也是遵循原型設計模式嗎? 它是否僅創建對象一次,並在隨後的請求調用創建對象上的clone()方法來創建新對象?以下原型設計模式的春天原型

此外,如果有人可以在JDK,Spring,Hibernate或任何J2EE框架中提供原型示例。

+0

,我會說,這應該已被要求作爲兩個獨立的問題開始。首先 - 我還沒有深入研究[源代碼](https://github.com/spring-projects/spring-framework),但如果它確實使用原型模式,我會非常驚訝。對於你的第二個問題:http://en.wikipedia.org/wiki/Prototype_pattern#Java_Example – Floegipoky 2014-10-28 21:05:59

回答

0

Spring不使用原型模式,它使用反射。 另外,爲了使用clone(),它必須以某種方式繼承一個bean,因爲clone()是受保護的,因此它也不使用clone()。

這裏是

org.springframework.beans.factory.support.SimpleInstantiationStrategy 

代碼片段在這裏你可以看到使用java.lang.reflect.Constructor中和java.lang.Class中的反射法:

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner) { 

    if (beanDefinition.getMethodOverrides().isEmpty()) { 
     Constructor<?> constructorToUse; 
     synchronized (beanDefinition.constructorArgumentLock) { 
      constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod; 
        ... 
         constructorToUse = clazz.getDeclaredConstructor((Class[]) null); 
        ... 
       } 
       ... 

    } 
    ... 
} 

所以說,原型用於表明在每次調用getBean時,都會得到一個具有相同屬性的新實例。然而,這不僅僅是對構造函數的簡單調用,因爲您將得到一個bean,其中所有的依賴關係都是有線的,並且其他屬性都設置好了,所以從某種意義上說,它是一個原型。或者至少它很適合這個概念。

0

我沒有挖成春源代碼,但我認爲豆類在春季prototype範圍使用clone()方法不會創建,因爲它不是強制執行Cloneable接口這些bean。

此外,假設它使用clone()創建它們。如果有人期待深拷貝而不是淺拷貝,那將是危險的。

您可以隨時測試並找到答案。

1

沒有彈簧不使用克隆來創建原型範圍實例。

下面是)從AbstractBeanFactory.doGetBean(採取的代碼段函數:

// Create bean instance. 
if (mbd.isSingleton()) { 
    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { 
     @Override 
     public Object getObject() throws BeansException { 
      try { 
       return createBean(beanName, mbd, args); 
      } 
      catch (BeansException ex) { 
       // Explicitly remove instance from singleton cache: It might have been put there 
       // eagerly by the creation process, to allow for circular reference resolution. 
       // Also remove any beans that received a temporary reference to the bean. 
       destroySingleton(beanName); 
       throw ex; 
      } 
     } 
    }); 
    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); 
} 

else if (mbd.isPrototype()) { 
    // It's a prototype -> create a new instance. 
    Object prototypeInstance = null; 
    try { 
     beforePrototypeCreation(beanName); 
     prototypeInstance = createBean(beanName, mbd, args); 
    } 
    finally { 
     afterPrototypeCreation(beanName); 
    } 
    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); 
} 

的createBean方法調用歸結爲以下代碼:

BeanUtils.instantiateClass(constructorToUse); 
0

號春範圍如原型singletone不嚴格遵循設計模式。範圍的命名被用來直觀地建議行爲容器提供的行爲。

這樣你就可以在容器中創建一個「singleton」模式,並在容器外創建另一個對象。同樣,「原型」模式不必實現「克隆」功能。

你可能想看看這個鏈接,以及:
Singleton design pattern vs Singleton beans in Spring container

更復雜的解釋在這裏:
https://springframework.guru/gang-of-four-design-patterns/prototype-pattern/