Question

I am using Java7 and Spring3. I have below classes.

Request.java

public interface Request {
  public void doProcess();

}

RequestImpl.java

    @Transactional
    public class RequestImpl implements Request{

     private String name;
     private String age;

     //setters and getters

     public void doProcess(){

      //use name and age and call third party class which will save data into database

      }
}

SpringConfig.xml

<bean id="request" class="pkg.RequestImpl.java" />

Now clients will use RequestImpl as below.

RequestImplreq = (RequestImpl)applicationContext.getBean("request");
req.setName("someName");
req.setAge("20");
req.doProcess();

Now my question is do i need to declare above RequestImpl.java scope as prototype or singleton?

Thanks!

Was it helpful?

Solution

IMHO you are not working well: processes and data to process should be separated (Can DTOs be spring managed beans?) so doProcess() should be defined as doProcess(name,age) or shaded behind a factory or something similar.
Probably the best option is to define

public interface Request {
  public void doProcess(String name,String age);
}

@Transactional
public class RequestImpl implements Request{
  public void doProcess(String name,String age){
    // do what you want
  }
}

your SpringConfig.xml stay the same and call code will change to:

Request req= applicationContext.getBean(Request.class);
req.doProcess("someName", "20");

Beside all, perform a ApplicationContext.getBean() and cast result to an implementation is (usually) bad pratice because Spring can proxy returned object and cast to implementation will fail with a ClassCastException

OTHER TIPS

@user3269829 : By default the scope would be singleton now it is totally depend upon your requirement, if you want a bean object for every request then you can go for "prototype" and if you want to share single bean object among the multiple request then you can go for "singleton"

It depends on how your third party class is implemented. If you want to ensure a single instance of your class you can use factory-method of spring beans and ensure single instance.

Check "3.3.2.2 Instantiation with a static factory method" part of Spring Documentation

It should look like this in bean definition:

<!-- the factory bean, which contains a method called createInstance() -->
<bean id="serviceLocator" class="examples.DefaultServiceLocator">
  <!-- inject any dependencies required by this locator bean -->
</bean>

<!-- the bean to be created via the factory bean -->
<bean id="clientService"
      factory-bean="serviceLocator"
      factory-method="createClientServiceInstance"/>

and singleton creator:

public class DefaultServiceLocator {
  private static ClientService clientService = new ClientServiceImpl();
  private DefaultServiceLocator() {}

  public ClientService createClientServiceInstance() {
    return clientService;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top