What is the best practice: Use prototype bean instead of new () operator

Viewed 466

I am trying to understand what would be the correct usage of Spring prototype bean. May be the following code sample will help in you understanding my dilemma:

List<ClassA> caList = new ArrayList<ClassA>();
    for (String name : nameList) {
        ClassA ca = new ClassA();

    //or Shall I use protypebean, using method lookup I can inject the dependency of ClassA. 
    // ClassA ca = getPrototypeClassA();

        ca.setName(name);
        caList.add(ca);
    }

So my exact point is in this scenario shall I go with method injection or new() operator. Provide your view with justification.

3 Answers

You can make use of either of the ways, because ultimately client code is responsible for handling the life-cycle of the prototype bean rather than spring container.

According to Spring-docs,

In some respects, you can think of the Spring containers role when talking about a prototype-scoped bean as somewhat of a replacement for the Java 'new' operator. All lifecycle aspects past that point have to be handled by the client.

Spring does not manage the complete lifecycle of a prototype bean: the container instantiates, configures, decorates and otherwise assembles a prototype object, hands it to the client and then has no further knowledge of that prototype instance. It is the responsibility of the client code to clean up prototype scoped objects and release any expensive resources that the prototype bean(s) are holding onto.

If ClassA needs to have @Autowired references, then go for a prototype bean.

Otherwise a simple POJO (that the Spring container is unaware of) will do.

It seems that your instance need some runtime values in order to initialise properly. In such case ,it depends on if you need to use spring feature such as AOP for the ClassA instance. If yes , go with the method injection .If not , you can consider using factory pattern . Much more OO and cleaner to me :

Something like the following . You should get the idea.

@Component
public class FactoryForClassA {

    @Autowired
    private FooBean someDependencyForClassA;


    public ClassA create(String name){
        ClassA a = new ClassA(someDependencyForClassA);
        a.setName(name);
        return a;
    }
}

And the client code:

@Autowired
private FactoryForClassA factoryForClassA;

List<ClassA> caList = new ArrayList<ClassA>();
for (String name : nameList) {
    ClassA a = factoryForClassA.create(name);
    caList.add(ca);
}
Related