9

Spring provides bean scope as "Prototype". Means whenever bean is required in application, Spring container will create a fresh/new instance of bean. Does is follow prototype design pattern also? Does it create object only once and in subsequent request calls clone() method on created object to create new object?

Also if someone can provide example of prototype in JDK, Spring, Hibernate or any J2EE framework.

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
vineeshchauhan
  • 765
  • 2
  • 7
  • 14
  • I'll start by saying that this should have been asked as two separate questions. For your first- I haven't dug into the [source code](https://github.com/spring-projects/spring-framework), but I'd be very surprised if it actually does utilize the prototype pattern. For your second quesiton: http://en.wikipedia.org/wiki/Prototype_pattern#Java_Example – Floegipoky Oct 28 '14 at 21:05

4 Answers4

3

No spring does not use cloning to create prototype scoped instances.

Below is the code snippet taken from AbstractBeanFactory.doGetBean() function:

// 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);
}

The createBean method call boils down to below code:

BeanUtils.instantiateClass(constructorToUse);
Noor
  • 603
  • 1
  • 6
  • 15
2

Spring does not use the Prototype Pattern, it uses reflection. Plus, in order to use clone() it would have to subclass somehow a bean, because clone() is protected, so it does not use clone() either.

Here is a code fragment from

org.springframework.beans.factory.support.SimpleInstantiationStrategy

where you can see the use of java.lang.reflect.Constructor and java.lang.Class reflection method:

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);
                    ...
                }
                ...

    }
    ...
}

So the term prototype is used to suggest that at every call to getBean, you'll get a new instance with the same properties. This is more than a simple call to a constructor however, because you'll get a bean with all dependencies wired and other properties set, so in a sense it is a prototype. Or at least it fits the concept very well.

Matei Florescu
  • 1,155
  • 11
  • 23
0

I have not dug into Spring source code, but I think Beans with prototype scope in Spring are not created using clone() method because it is not mandatory to implement the Cloneable interface for those beans.

Moreover, suppose it is creating them using clone(). It would then be dangerous if someone is expecting deep copy instead of shallow copy.

You can always test it and find the answer.

Magnilex
  • 11,584
  • 9
  • 62
  • 84
Rakesh Chauhan
  • 413
  • 4
  • 7
0

No. Spring scopes such as prototype or singletone do not follow strictly design patterns. The naming of scopes was used to intuitively suggest behavior container provides.

This way you can have a "singleton" pattern within the container and create another object outside of the container. Similarly "prototype" pattern does not have to implement "clone" functionality.

You may want to look into this link as well:
Singleton design pattern vs Singleton beans in Spring container

More elaborate explanations here:
https://springframework.guru/gang-of-four-design-patterns/prototype-pattern/

Witold Kaczurba
  • 9,845
  • 3
  • 58
  • 67