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