简体   繁体   English

Spring bean配置使用单例还是原型?

[英]Spring bean configuration to use singleton or prototype?

I am using Java7 and Spring3. 我正在使用Java7和Spring3。 I have below classes. 我有以下课程。

Request.java Request.java

public interface Request {
  public void doProcess();

}

RequestImpl.java 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 SpringConfig.xml

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

Now clients will use RequestImpl as below. 现在,客户将使用如下所示的RequestImpl。

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? 现在我的问题是我需要在RequestImpl.java范围内声明为原型还是单例?

Thanks! 谢谢!

@ user3269829:默认情况下,作用域为singleton这完全取决于您的要求,如果每个请求都需要一个bean对象,则可以使用“ prototype ”,如果要在多个请求中共享单个bean对象,则你可以去“ 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. 如果要确保类的单个实例,可以使用spring bean的工厂方法并确保单个实例。

Check "3.3.2.2 Instantiation with a static factory method" part of Spring Documentation 检查Spring文档中的 “ 3.3.2.2使用静态工厂方法实例化”部分

It should look like this in bean definition: 在bean定义中应该看起来像这样:

<!-- 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;
  }
}

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. 恕我直言,您的工作状况不佳:流程和要处理的数据应该分开( DTO可以是Spring管理的bean吗? ),因此doProcess()应该定义为doProcess(name,age)或在工厂后面或类似的地方doProcess(name,age)阴影。
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: 您的SpringConfig.xml保持不变,调用代码将更改为:

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 此外,执行一个ApplicationContext.getBean()并将结果强制转换为实现(通常)是不明智的做法,因为Spring可以代理返回的对象并将对象强制转换为实现将失败,并发生ClassCastException

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM