[英]What is a right way to initialize fields in Spring Beans?
I'm wondering how should I initialize fields in Spring Beans?我想知道我应该如何初始化 Spring Beans 中的字段? Here is several possible solutions:以下是几种可能的解决方案:
1. Initialize fields directly on declaration 1. 直接在声明时初始化字段
import org.springframework.stereotype.Component;
@Component
public class DeclarationInit {
private final int field = Integer.MAX_VALUE;
public int getField() {
return field;
}
}
2. Initialize fields using @Value
annotation 2.使用@Value
注解初始化字段
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component
public class ValueInit {
@Value("#{T(Integer).MAX_VALUE}")
private int field;
public int getField() {
return field;
}
}
3. Initialize fields using @Autowired
annotation 3.使用@Autowired
注解初始化字段
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class AutowiredInit {
private int field;
@Autowired
private void initField() {
field = Integer.MAX_VALUE;
}
public int getField() {
return field;
}
}
4. Initialize fields using @PostConstruct
annotation 4.使用@PostConstruct
注解初始化字段
import javax.annotation.PostConstruct;
import org.springframework.stereotype.Component;
@Component
public class PostConstructInit {
private int field;
@PostConstruct
private void initField() {
field = Integer.MAX_VALUE;
}
public int getField() {
return field;
}
}
All tests succeeds and do not show any difference:所有测试都成功并且没有显示任何差异:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SomeTestContextConfiguration.class)
public class FieldInitTest {
@Autowired
private DeclarationInit declarationInit;
@Autowired
private ValueInit valueInit;
@Autowired
private AutowiredInit autowiredInit;
@Autowired
private PostConstructInit postConstructInit;
@Test
public void shouldInitializeFieldOnDeclaration() {
assertThat(declarationInit.getField(), equalTo(Integer.MAX_VALUE));
}
@Test
public void shouldInitializeFieldWithValueAnnotation() {
assertThat(valueInit.getField(), equalTo(Integer.MAX_VALUE));
}
@Test
public void shouldInitializeFieldWithAutowiredSetter() {
assertThat(autowiredInit.getField(), equalTo(Integer.MAX_VALUE));
}
@Test
public void shouldInitializeFieldWithPostConstruct() {
assertThat(postConstructInit.getField(), equalTo(Integer.MAX_VALUE));
}
}
Are this declarations equal to each other or should I use only one of them or neither of them?这些声明是否彼此相等,还是我应该只使用其中一个或两个都不使用?
Assuming the value is a constant, the first option is the simplest to understand and works without Spring, simplifying unit testing.假设该值是一个常量,第一个选项是最容易理解的,并且在没有 Spring 的情况下也能工作,从而简化了单元测试。
The second and fourth option are more complex and introduce an unnecessary dependency on the Spring container without any benefit.第二个和第四个选项更复杂,并且引入了对 Spring 容器的不必要依赖,没有任何好处。 The third option is outright bizarre, since you're using @Autowired
and not performing dependency injection.第三个选项非常奇怪,因为您使用的是@Autowired
而不是执行依赖注入。
I believe spring offers all those options because you might run into different requirements...我相信 spring 提供了所有这些选项,因为您可能会遇到不同的要求......
If you want MAX_INT
and there's no way on earth anyone needs to initialize it differently, then it's enough to declare int field = Integer.MAX_INT
regardless of Spring.如果你想要MAX_INT
并且地球上没有任何人需要以不同的方式初始化它,那么无论 Spring 是什么,声明int field = Integer.MAX_INT
就足够了。
If you do want to allow other initial configurations, then you can initialize it using @Autowired
, or through a constructor arg, or setter/getter... it's a matter of taste.如果您确实想允许其他初始配置,那么您可以使用@Autowired
或通过构造函数 arg 或 setter/getter 对其进行初始化......这是一个品味问题。
@PostConstruct
is more suitable for complex situations, eg if your field needs to be calculated based on other injected fields. @PostConstruct
更适合复杂的情况,例如,如果您的字段需要根据其他注入的字段进行计算。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.