singleton和prototype bean有什么区别?

Ami*_*ira 38 spring dependency-injection

我是春天的新手,我读到了这个:

基本上bean有一个范围,用于定义它们在应用程序中的存在

Singleton:表示每个Spring IOC容器的单个bean定义到单个对象实例.

原型:表示对任意数量的对象实例的单个bean定义.

什么是"对象实例".

Luc*_*uke 74

原型范围 =每次注入/查找时都会创建一个新对象.它将new SomeClass()每次使用.

Singleton scope = (默认)每次注入/查找时返回相同的对象.这里它将实例化一个实例,SomeClass然后每次返回它.

也可以看看:

  • 以及它如何影响应用程序?每个上下文有单个实例vs每次注入一个实例?是否会出现并发/线程问题? (3认同)
  • 关于以上答案的问题:如果是单例作用域,则在启动时上下文的生存期内创建一个对象(或可以是惰性的)。原型范围呢?是否在上下文启动时创建任何对象?还是基于完整的请求? (2认同)

lor*_*uko 17

让我们只是通过代码查看.

以下是具有默认singleton范围的TennisCoach Bean

@Component
@Scope("singleton")
public class TennisCoach implements Coach {

    public TennisCoach(){

    }

    @Autowired
    public void setFortuneService(FortuneService fortuneService) {
        this.fortuneService = fortuneService;
    }

    @Override
    public String getDailyWorkout() {
        return "Practice your backhand volley";
    }

    @Override
    public String getDailyFortune() {
        return "Tennis Coach says : "+fortuneService.getFortune();
    }

}
Run Code Online (Sandbox Code Playgroud)

以下是具有原型范围的TennisCoach Bean

@Component
@Scope("prototype")
public class TennisCoach implements Coach {

    public TennisCoach(){
        System.out.println(">> TennisCoach: inside default constructor");
    }

    @Autowired
    public void setFortuneService(FortuneService fortuneService) {
        System.out.println(">> Tennis Coach: inside setFortuneService");
        this.fortuneService = fortuneService;
    }

    @Override
    public String getDailyWorkout() {
        return "Practice your backhand volley";
    }

    @Override
    public String getDailyFortune() {
        return "Tennis Coach says : "+fortuneService.getFortune();
    }

}
Run Code Online (Sandbox Code Playgroud)

以下是Main类:

public class AnnotationDemoApp {

    public static void main(String[] args) {


        // read spring config file
        ClassPathXmlApplicationContext context =
            new ClassPathXmlApplicationContext("applicationContext.xml");

       // get the bean from the spring container
       Coach theCoach = context.getBean("tennisCoach",Coach.class);
       Coach alphaCoach = context.getBean("tennisCoach",Coach.class);
       // call a method on the bean
       System.out.println("Are the two beans same :" + (theCoach==alphaCoach));

       System.out.println("theCoach : " + theCoach);
       System.out.println("alphaCoach: "+ alphaCoach);


       context.close()

    }
}
Run Code Online (Sandbox Code Playgroud)

对于单例范围,输出为:

Are the two beans same :true
theCoach : com.springdemo.TennisCoach@2a53142
alphaCoach: com.springdemo.TennisCoach@2a53142
Run Code Online (Sandbox Code Playgroud)

对于原型范围,输出为:

Are the two beans same :false
theCoach : com.springdemo.TennisCoach@1b37288
alphaCoach: com.springdemo.TennisCoach@1a57272
Run Code Online (Sandbox Code Playgroud)

希望这能回答你的问题.:d

  • 很好的例子,您什么时候会选择哪个范围? (4认同)

sha*_*shi 11

添加到上面..不要混淆java单例.根据JAVA规范,singleton意味着每个JVM只会创建该bean的一个实例.但是在spring中,singleton意味着每个应用程序上下文将创建一个特定bean的实例.因此,如果您的应用程序有多个上下文,那么您仍然可以为该bean提供多个实例.

  • 部分正确部分错误。查看所有内容取决于您在配置文件中定义 bean 时使用的范围。默认情况下,java 将作用域设为单例。有五个可用范围:- 1.singleton – 每个 Spring IoC 容器返回一个 bean 实例 2.prototype – 每次请求时返回一个新的 bean 实例 3.request – 每个 HTTP 请求返回一个 bean 实例。* 4.session – 每个 HTTP 会话返回一个 bean 实例。* 5.globalSession – 每个全局 HTTP 会话返回一个 bean 实例。* (2认同)