Spring將bean作用域提供爲「原型」。意味着當應用程序需要bean時,Spring容器將創建一個新的/新的bean實例。 也是遵循原型設計模式嗎? 它是否僅創建對象一次,並在隨後的請求調用創建對象上的clone()方法來創建新對象?以下原型設計模式的春天原型
此外,如果有人可以在JDK,Spring,Hibernate或任何J2EE框架中提供原型示例。
Spring將bean作用域提供爲「原型」。意味着當應用程序需要bean時,Spring容器將創建一個新的/新的bean實例。 也是遵循原型設計模式嗎? 它是否僅創建對象一次,並在隨後的請求調用創建對象上的clone()方法來創建新對象?以下原型設計模式的春天原型
此外,如果有人可以在JDK,Spring,Hibernate或任何J2EE框架中提供原型示例。
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,其中所有的依賴關係都是有線的,並且其他屬性都設置好了,所以從某種意義上說,它是一個原型。或者至少它很適合這個概念。
我沒有挖成春源代碼,但我認爲豆類在春季prototype
範圍使用clone()
方法不會創建,因爲它不是強制執行Cloneable
接口這些bean。
此外,假設它使用clone()
創建它們。如果有人期待深拷貝而不是淺拷貝,那將是危險的。
您可以隨時測試並找到答案。
沒有彈簧不使用克隆來創建原型範圍實例。
下面是)從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);
號春範圍如原型或singletone不嚴格遵循設計模式。範圍的命名被用來直觀地建議行爲容器提供的行爲。
這樣你就可以在容器中創建一個「singleton」模式,並在容器外創建另一個對象。同樣,「原型」模式不必實現「克隆」功能。
你可能想看看這個鏈接,以及:
Singleton design pattern vs Singleton beans in Spring container
更復雜的解釋在這裏:
https://springframework.guru/gang-of-four-design-patterns/prototype-pattern/
,我會說,這應該已被要求作爲兩個獨立的問題開始。首先 - 我還沒有深入研究[源代碼](https://github.com/spring-projects/spring-framework),但如果它確實使用原型模式,我會非常驚訝。對於你的第二個問題:http://en.wikipedia.org/wiki/Prototype_pattern#Java_Example – Floegipoky 2014-10-28 21:05:59