首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring prototype遵循prototype设计模式

Spring prototype遵循prototype设计模式
EN

Stack Overflow用户
提问于 2014-10-28 21:45:50
回答 4查看 2.9K关注 0票数 7

Spring提供了bean作用域作为“原型”。意味着只要应用程序中需要bean,Spring容器就会创建一个新的bean实例。是否也遵循原型设计模式?它是否只创建一次对象,并在随后的请求中调用已创建对象上的clone()方法来创建新对象?

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

EN

回答 4

Stack Overflow用户

发布于 2016-04-14 19:59:54

没有spring不使用克隆来创建原型作用域实例。

下面是摘自AbstractBeanFactory.doGetBean()函数的代码片段:

代码语言:javascript
复制
// 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方法调用归结为以下代码:

代码语言:javascript
复制
BeanUtils.instantiateClass(constructorToUse);
票数 3
EN

Stack Overflow用户

发布于 2014-10-29 19:53:41

Spring不使用Prototype模式,它使用反射。另外,为了使用clone(),它必须以某种方式子类化一个bean,因为clone()是受保护的,所以它也不使用clone()。

下面是来自

代码语言:javascript
复制
org.springframework.beans.factory.support.SimpleInstantiationStrategy

在这里您可以看到java.lang.reflect.Constructor和java.lang.Class反射方法的使用:

代码语言:javascript
复制
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);
                    ...
                }
                ...

    }
    ...
}

因此,术语prototype用于表示每次调用getBean时,都会获得一个具有相同属性的新实例。然而,这不仅仅是对构造函数的简单调用,因为您将获得一个连接了所有依赖项并设置了其他属性的bean,因此在某种意义上它是一个原型。或者至少它非常符合这个概念。

票数 2
EN

Stack Overflow用户

发布于 2015-05-04 21:05:59

我没有深入研究Spring的源代码,但我认为在Spring中具有prototype作用域的bean不是使用clone()方法创建的,因为为这些bean实现Cloneable接口并不是强制性的。

此外,假设它使用clone()创建它们。如果有人期望深层复制而不是浅层复制,那么这将是危险的。

你总是可以测试它并找到答案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26609980

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档