我试图了解Symfony2框架。
来自Java / Spring背景,我意识到Symfony2中的Scope与Spring中的Scope不同。此外,使用Symfony3 Scope is deprecated,但我们可以指定服务是否共享。
这是什么意思?
服务容器是否会保留服务对象直到其生命周期?这是否意味着我可以使用成员变量来跨请求保存有状态信息? (我不确定这是否真的可能,因为显然不会发生)。
因此它可能不会跨越请求。服务容器的生命周期是否与请求相等?因为我注意到如果我有两个消费者使用的依赖关系,如果我设置shared: false
,每个消费者会得到一个不同的状态"依赖。但他们基本上处于相同的请求中。
指定shared: false
到底意味着什么?或者shared: true
是什么意思?
答案 0 :(得分:5)
服务的生命周期是单一请求。
共享服务意味着每次访问服务时都会返回相同的实例。如果您设置shared: false
,则每次请求服务时都会创建新的服务实例。
您还提到了2位消费者。我相信您将您的消费者作为独立的流程运行,因此这些是不同的请求和不同的范围。
答案 1 :(得分:4)
尽管Mantas在大多数情况下是正确的,但在某些边缘情况下,说明生命周期是单一请求可能会产生误导。
基本上,只要内核存在,服务容器就会存在。服务容器在Kernel::boot()
期间初始化,这是内核第一次处理请求时调用的。 (例如,请参阅前端控制器app.php。)容器在Kernel::shutdown()
或者PHP进程退出时被丢弃。
因此,当您让内核处理多个请求时,或者在内核的生命周期内执行子请求时,服务容器仍然存在,并且服务中的任何状态都会被保留。
以下面两个代码片段为例:
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$responseOne = $kernel->handle($requestOne); // Container initialised
$responseOne->send();
$kernel->terminate($requestOne, $responseOne);
$responseTwo = $kernel->handle($requestTwo); // Container still exists
$responseTwo->send();
$kernel->terminate($requestTwo, $responseTwo);
$kernel->shutdown(); // Container destructed
和
$kernel = new AppKernel('prod', false);
$kernel->loadClassCache();
$responseOne = $kernel->handle($requestOne); // Container initialised
$responseOne->send();
$kernel->terminate($requestOne, $responseOne);
$kernel->shutdown(); // Container destructed
$responseTwo = $kernel->handle($requestTwo); // New Container initialised
$responseTwo->send();
$kernel->terminate($requestTwo, $responseTwo);
// PHP exits, container destructed
在大多数情况下,您的PHP进程将为您的Web服务器提供一个请求的生命周期。但是,在某些情况下,您可以利用在请求之间保持内核(包括服务容器)的能力。例如,有php-pm project基本上保持你的内核存活并向它发出请求。
这将大大提高性能(构建容器并为每个请求反复初始化捆绑包没有开销)。另一方面,您的服务将被共享用于多个请求,并且可能针对多个用户,这意味着在您的服务中保存状态可能会带来很大的安全风险。
因此,请始终将您的数据类与服务分开,并且不要在服务中存储数据。 Symfony就是一个很好的例子,它使用Request和Response类来分离数据。