java - Spring @Bean 方法可以返回实例字段吗?
问题描述
以下 Spring bean 声明似乎“按预期”运行和表现:
@Configuration
public 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 是否仍然管理's value?
这个问题不是Spring @Bean at method return already created bean的重复,这引出了问题,但该问题可能正确识别答案。
解决方案
如果将 Spring IoC 存储在现场,您将失去 Spring IoC 所提供的好处,甚至可能导致某些范围内的意外行为。
如果范围是singleton
或者application
因为它只会调用foo()
一次,这将起作用。但是如果范围更改为protoptype
(每次都创建一个新实例)。那么它可能会导致意外的行为。因为你存储foo
在一个字段中,所以它仍然会表现为singleton
,因为它总是指向同一个实例。
如果您在构造函数中启动类,它将始终启动,即使配置文件未处于活动状态。Spring 不能(也不应该)检测实例的启动位置。如果配置文件未激活,Spring IoC 将不会调用该方法。除了上面的解释之外,在方法本身中启动实例会更安全。
推荐阅读
- angular - 角度流内容到用户文件系统
- excel - 在同一工作簿中的多个工作表上运行公式
- html - Angular 9 - 当用户输入内容时扩展文本框的高度,并在点击它时恢复正常大小
- haskell - 在haskell中查找整数的位长
- docker - 如何在 Windows os 中为计算机视觉注释工具 cvat 安装大数据集的共享路径,同时为其构建 docker 容器?
- aem - aem6.5 中富文本 rte 插件中的超链接空间问题
- javascript - 如何在反应原生的对象中访问父母的兄弟姐妹值?
- reactjs - 如何在不加载所有组件的情况下创建多个独立页面
- python - 使用 json 导入二进制字符串
- jquery - Jquery:输入搜索数据表未过滤