From 6a43170156f754fa33aa860d22172d2086c0a1c6 Mon Sep 17 00:00:00 2001 From: Yurun Date: Mon, 18 Dec 2023 15:40:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=AF=B9=E8=B1=A1=E5=9C=A8?= =?UTF-8?q?=20=5F=5Finit()=20=E6=96=B9=E6=B3=95=E4=B8=AD=E5=88=9D=E5=A7=8B?= =?UTF-8?q?=E5=8C=96=E6=97=B6=E6=8A=9B=E5=87=BA=E5=BC=82=E5=B8=B8=EF=BC=8C?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E8=BF=98=E8=83=BD=E8=A2=AB=E6=AD=A3=E5=B8=B8?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E7=9A=84=E9=97=AE=E9=A2=98=20(#666)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复对象在 __init() 方法中初始化时抛出异常,对象还能被正常使用的问题 * 修复 --- src/Bean/Container.php | 29 ++++++++++++++++++------ tests/unit/Component/Bean/InitClass.php | 30 +++++++++++++++++++++++++ tests/unit/Component/Tests/BeanTest.php | 18 +++++++++++++++ 3 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 tests/unit/Component/Bean/InitClass.php diff --git a/src/Bean/Container.php b/src/Bean/Container.php index 6ab0bead9..bf62614a6 100644 --- a/src/Bean/Container.php +++ b/src/Bean/Container.php @@ -162,16 +162,32 @@ private function __newInstance(string $id, array $params, bool $allowStore): mix if ($data['recursion'] ?? false) { - // @phpstan-ignore-next-line - BeanFactory::initInstance($object, $params, $originId); - if ($stored && $object !== $beanObjects[$originId]) + if ($stored) { - // 防止类 __init() 方法有协程上下文切换,导致单例被覆盖 - return $beanObjects[$originId]; + try + { + BeanFactory::initInstance($object, $params, $originId); + if ($object !== $beanObjects[$originId]) + { + // 防止类 __init() 方法有协程上下文切换,导致单例被覆盖 + return $beanObjects[$originId]; + } + } + catch (\Throwable $th) + { + if ($object === $beanObjects[$originId]) + { + unset($beanObjects[$originId]); + } + throw $th; + } + } + else + { + BeanFactory::initInstance($object, $params, $originId); } } - // @phpstan-ignore-next-line return $object; } @@ -261,7 +277,6 @@ public function getSingleton(string $id, mixed ...$params): mixed $singletonObjects[$originId] = $object; } - // @phpstan-ignore-next-line return $object; } diff --git a/tests/unit/Component/Bean/InitClass.php b/tests/unit/Component/Bean/InitClass.php new file mode 100644 index 000000000..27133dda4 --- /dev/null +++ b/tests/unit/Component/Bean/InitClass.php @@ -0,0 +1,30 @@ +throw = App::get('InitClass.throw'); + } + + public function __init(): void + { + if ($this->throw) + { + throw new \RuntimeException('gg'); + } + } + + public function isThrow(): bool + { + return $this->throw; + } +} diff --git a/tests/unit/Component/Tests/BeanTest.php b/tests/unit/Component/Tests/BeanTest.php index 3b402c659..2709af6aa 100644 --- a/tests/unit/Component/Tests/BeanTest.php +++ b/tests/unit/Component/Tests/BeanTest.php @@ -11,6 +11,7 @@ use Imi\Test\Component\Bean\BeanA; use Imi\Test\Component\Bean\BeanB; use Imi\Test\Component\Bean\BeanC; +use Imi\Test\Component\Bean\InitClass; use Imi\Test\Component\Enum\TestEnumBean; use Imi\Test\Component\Enum\TestEnumBeanBacked; use Imi\Util\Imi; @@ -415,6 +416,23 @@ public function testEnumBean(): void $this->assertEquals(TestEnumBeanBacked::B, $bean->getEnum3()); } + public function testInitThrow(): void + { + App::set('InitClass.throw', true); + try + { + App::getBean(InitClass::class); + } + catch (\Throwable $th) + { + $this->assertEquals('gg', $th->getMessage()); + } + + App::set('InitClass.throw', false); + $object = App::getBean(InitClass::class); + $this->assertFalse($object->isThrow()); + } + // @phpstan-ignore-next-line private function test1(): self {