2017-07-01 44 views
0

我开始使用Spring MVC开发REST API。 我将它部署在一个Tomcat容器中,它的功能就像一个魅力。与Tomcat混淆Spring IoC容器

由于Tomcat负责为每个请求创建一个新线程(请纠正我,如果我错了),我想知道Spring如何处理这个来管理IoC(控制反转)容器。

例子:我有以下服务

@Service 
public class UserService{ 
    private String username; 

    public setUsername(String username){ 
     this.username = username; 
    } 

    public getUsername(){ 
     return this.username; 
    } 
} 

所以基本上Spring将创建这个独立的,并使其可用于每个人。

如果请求出现并设置“foobar”用户名,下一个请求(来自不同用户)的“getUsername”调用是否返回“foobar”? Spring如何管理这种情况?

问候

+3

无论有多少个线程,都有一个实例。春天什么都不管。与状态**共享单身**是你通常不应该做的事情。 –

回答

0

默认春豆单作用域,这意味着春天创建bean的实例,并给所有的线程提供相同的实例。由于你的bean是有状态的(用户名),所以这个状态也会被所有的线程共享,Spring在这里没有任何魔法。 因此,如果一个线程设置用户名“xyz”,那么第二个线程会将其视为“xyz”。

1

与其他人一样,默认情况下,Spring创建Singleton范围bean,以便每个线程都会看到与其他线程相同的类级别状态。在这种情况下,最好避免在应用程序中维护类级别的状态,并在方法范围内通过应用程序传递所有必需的数据,从而使它们成为线程安全的。

但是,让我们来创建每个线程的bean的新实例,如果你想要的话。你可以用@Scope(“prototype”)注释你的bean,并且你会得到每个线程的bean实例。默认值是@Scope(“singleton”)。如果您需要它们,还有其他几个范围可用。

+0

是否意味着默认情况下我应该将原型范围放在服务上? – Pascal

+0

是的,如果你确定每次都想要一个新实例并且希望在类/对象中维护状态,那么就使用原型范围。对于大量的并发线程/用户,您可能会看到对所创建对象的更多实例的性能影响。所以,这是一个需要权衡的折衷方案 - 在内存中存在更多对象实例的潜在性能受到影响,或重新设计应用程序以避免维护对象中的状态,并恢复为使用单例。 – MickG

0

docs

只有一个共享一个singleton bean的实例进行管理,并返回用于与ID豆类或ID​​S在一个特定的bean实例bean定义 结果匹配所有 请求春天 容器。换句话说,当你定义一个bean定义并且它作为一个单例作为作用域时,Spring IoC容器恰好创建了一个由该bean定义定义的对象的一个​​实例 。此单个实例存储在此类单例bean的缓存中,并且该命名Bean的所有后续请求和引用都返回缓存的对象 。