2014-10-28 52 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/