Java 通过组件构造函数自动连接静态成员
我知道这是汇编的,但我的问题是,这是个好主意吗?我很好奇为什么这不是个好主意。更好的是,如果Java 通过组件构造函数自动连接静态成员,java,spring,static,dependency-injection,Java,Spring,Static,Dependency Injection,我知道这是汇编的,但我的问题是,这是个好主意吗?我很好奇为什么这不是个好主意。更好的是,如果SomeStaticClass是@组件,但它也必须是MyComponent的静态成员,那么还有其他选择吗。我的理解是,其糟糕的设计有弹簧自动线静态成员。根据我所读到的,我仍然不太明白为什么。假设我有以下几点: @Component public final class MyComponent { private static SomeStaticClass someStaticClass; @
SomeStaticClass
是@组件
,但它也必须是MyComponent
的静态成员,那么还有其他选择吗。我的理解是,其糟糕的设计有弹簧自动线静态成员。根据我所读到的,我仍然不太明白为什么。假设我有以下几点:
@Component
public final class MyComponent {
private static SomeStaticClass someStaticClass;
@Autowired
MyComponent(SomeStaticClass someStaticClass) {
MyComponent.someStaticClass = someStaticClass;
}
}
@Component
基本上意味着默认情况下您的bean是单体的。因此,在它里面有一个静态依赖关系没有多大意义。但是它将按照您所说的那样编译。SpringBean默认为单例,因此将someStaticClass
设置为实例字段,并保持您的代码干净且可测试。someStaticClass
没有理由是静态的。非最终静态字段是一种气味。默认情况下,所有SpringBean都是单例的,因此在设计类时不需要在此处使用静态字段。设计不好的原因如下:
静态
可变字段通常是一种糟糕的设计
- 使测试更加困难-一旦设置了此字段,它将在下一次测试中保持设置,可能会创建隐藏的相互依赖关系
- 如果希望有两个
MyComponent
实例,每个实例都具有不同的SomeStaticClass
,该怎么办?混乱
- 您不能通过
静态
字段或setter自动连线插入值,这是明确禁止的。这肯定是有原因的
- 你为什么需要这个?在
MyComponent
中是否有static
方法?为什么?
- 如果上述情况属实,在构造函数初始化该字段之前,如何防止调用
MyComponent.staticMethod()
?春天的全部意义在于返回人口充足、安全的豆子
这是一种糟糕的设计,因为生命周期不同。静态变量一旦初始化,即使在应用程序上下文关闭时也将继续存在
另一个不匹配是可能存在多个应用程序上下文。如果
SomeStaticClass
是注册表怎么办?正如托马斯兹指出的那样,这将导致混乱
此外,在初始化容器之前,也可能会访问变量。可能性比您预期的要大:容器中的一些bean可能在初始化期间调用MyComponent
的静态方法,而MyComponent
的初始化将在初始化之后执行(这是因为在本例中bean依赖项是隐式的,因此IoC容器不知道正确的顺序-您必须使用@DependsOn
注释)尽管存在设计缺陷,如果您需要使用上下文初始化静态变量,应该尽快完成
有几种可能性,其中一些与@Autowired
兼容:
- 让类实现
ApplicationListener
或使用ApplicationListener
刷新它
- 重写
onRefresh()
方法并刷新它
- 使bean定义成为第一个定义,singleton将按照注册的相同顺序实例化
- 使用
取决于其他一些早期安装的bean,消息源是一个很好的机会
很暗,但如果你真的需要它
另一个选项是手工编写BeanFactoryPostProcessor和注入静态字段