Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring prototype following prototype design pattern

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.

like image 857
vineeshchauhan Avatar asked Oct 28 '14 13:10

vineeshchauhan


2 Answers

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);
like image 55
Noor Avatar answered Oct 09 '22 09:10

Noor


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.

like image 38
Matei Florescu Avatar answered Oct 09 '22 09:10

Matei Florescu