以下 Spring bean 聲明似乎“按預期”運行和運行:@Configurationpublic class AppConfig { private final Foo foo; public AppConfig() { foo = new Foo(); } @Bean public Foo foo() { return foo; }}其中“如預期”的意思是“沒有明顯錯誤”。假設它Foo有一些復雜的生命周期(例如使用 管理外部資源AutoCloseable),這是一個有效且合理的聲明foo()嗎?我能找到的所有示例,無論是官方的還是非官方的,都表明foo實例應該在內部實例化foo(),而不是存儲在字段中和從字段中檢索。但是,我在任何文檔中都找不到明確的信息表明這應該或不應該是安全的。我能找到的最相關的文檔是關于 Spring IoC bean 生命周期的,例如https://docs.spring.io/spring/docs/5.1.0.RELEASE/spring-framework-reference/core.html#beans-factory -范圍。從字里行間可以看出,一個singleton或application范圍內的 bean 是有效有效的,因為當它不再有效時,應用程序就不再存在了。由于singleton是默認范圍,上面的聲明隱式有效。即使有適當的范圍,假設您引入了一個替代的、特定于配置文件的聲明@Bean("foo")@Profile("!test")public Foo realFoo() { return this.foo;}@Bean("foo")@Profile("test")public Foo testFoo() { return new TestFoo();}現在將this.foo始終被實例化,即使在激活test配置文件時也是如此?realFoo()如果是這樣,即使那個 bean 應該是不活動的,Spring 是否仍然管理它的值?這個問題不是Spring @Bean at method returning already created bean的重復,這回避了問題,但那個問題可能正確地確定了答案。
1 回答

BIG陽
TA貢獻1859條經驗 獲得超6個贊
如果將它存儲在字段中,您將失去 Spring IoC 必須提供的好處,甚至可能導致某些范圍的意外行為。
如果范圍是singleton
或application
因為它只會調用foo()
一次,這將起作用。但是如果范圍更改為protoptype
(每次都創建一個新實例)。然后它可能會導致意外行為。因為你存儲foo
在一個字段中,所以它仍然會表現得像singleton
,因為它總是指向同一個實例。
如果您在構造函數中啟動類,它將始終啟動,即使配置文件未處于活動狀態。Spring 不能(也不應該)檢測實例的啟動位置。如果配置文件未激活,Spring IoC 將不會調用該方法。除了上面的解釋,在方法本身中啟動實例會更安全。
添加回答
舉報
0/150
提交
取消