Spring 2.5.x+3.0.x: Create prototype instances from code

Here follow some snippets to show you the programmatically creation of prototype instances using Spring 2.5.6.SEC01.

a) Create a spring bean with scope “prototype”.

package springsample;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(value = "prototype")
public class Knife {
}

b) Create a spring bean and autowire a ProviderUtil instance (l. 12). The prototype instances are created at line 29 using ProviderUtils.

package springsample;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class KnifeJuggler {

    @Autowired
    ProviderUtil util;

    public void juggle() {
        List<Knife> list = new ArrayList<Knife>();

        for (int i = 0; i < 5; i++) {
            //create 5 prototype scoped instances
            list.add(createKnifeInstance());
        }

        //print each instance
        for (Knife knife : list) {
            System.out.println(knife);
        }
    }

    private Knife createKnifeInstance() {
        return util.getBeanByType(Knife.class);
    }
}

c) The “magic” is coded here. A utility bean named ProviderUtil is defined and the ApplicationContext is autowired (l. 14). The prototype bean now can be resolved using this context: Every time you call ctx.getBean(xxx) to get the bean a new instance will be returned (l. 24). (Because the scope of the target bean is “prototype”)

package springsample;

import java.util.Map;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class ProviderUtil {

    @Autowired
    private ApplicationContext ctx;

    public <T> T getBeanByType(final Class<T> claz) throws UnsupportedOperationException, BeansException {
        Map beansOfType = ctx.getBeansOfType(claz);
        final int size = beansOfType.size();
        switch (size) {
            case 0:
                throw new UnsupportedOperationException("No bean found of type" + claz);
            case 1:
                String name = (String) beansOfType.keySet().iterator().next();
                return claz.cast(ctx.getBean(name, claz));
            default:
                throw new UnsupportedOperationException("Ambigious beans found of type" + claz);
        }
    }
}

d) Enable annotation driven spring bean processing. This registers all Spring beans via annotations like @Component.


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd


http://www.springframework.org/schema/context


http://www.springframework.org/schema/context/spring-context-2.5.xsd"

>
 
    <context:component-scan base-package="springsample"/>
</beans>

e) Sample code to test these snippets

package springsample;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("newSpringXMLConfig.xml");
        //resolve by type
        KnifeJuggler juggler = ProviderUtil.getBeanByType(ctx, KnifeJuggler.class);
        juggler.juggle();
    }
}

e) When running this code 5 different prototype instance will be printed to stdout.


springsample.Knife@f9da4fc
springsample.Knife@36baa466
springsample.Knife@177f409c
springsample.Knife@236acdd1
springsample.Knife@38ee6681
BUILD SUCCESSFUL (total time: 0 seconds)


Alternative a) An alternative would be the usage of javax.inject.Provider from JSR 330, but this is not supported for Spring 2.5.x. Using javax.inject.Provider in Spring 3.0.6 works. Do not forget to include a JSR330-dependency (like JEE6-API in NetBeans).

The code is simpler again: Autowire a provider for the prototype bean (l. 13) and use the provider to get the prototype instance (l. 31).

package springsample;

import java.util.ArrayList;
import java.util.List;
import javax.inject.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component(value = "jugglername")
public class KnifeJuggler {

    @Autowired
    Provider<Knife> knifeProvider;

    public void juggle() {
        List<Knife> list = new ArrayList<Knife>();


        for (int i = 0; i < 5; i++) {
            //create 5 prototype scoped instances
            list.add(createKnifeInstance());
        }

        //print each instance
        for (Knife knife : list) {
            System.out.println(knife);
        }
    }

    private Knife createKnifeInstance() {
        return knifeProvider.get();
    }
}

Alternative b) Use ObjectFactory – see the sample at http://techo-ecco.com/blog/spring-prototype-scoped-beans-and-dependency-injection/

About these ads

2 thoughts on “Spring 2.5.x+3.0.x: Create prototype instances from code

  1. Pingback: How to create a list filled with instances of a prototype bean using annotations?QueryBy | QueryBy, ejjuit, query, query by, queryby.com, android doubt, ios question, sql query, sqlite query, nodejsquery, dns query, update query, insert query, kony, mobil

  2. Pingback: How to create a list filled with instances of a prototype bean using annotations? | Technology & Programming Answers

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s