在Spring Beans中初始化字段的正确方法是什么



我想知道如何初始化Spring Beans中的字段?以下是几种可能的解决方案:

1.直接在声明上初始化字段

import org.springframework.stereotype.Component;
@Component
public class DeclarationInit {
    private final int field = Integer.MAX_VALUE;
    public int getField() {
        return field;
    }
}

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.使用@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.使用@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;
    }
}

所有测试都成功,没有显示任何差异:

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));
    }
}

这些声明是相等的,还是我应该只使用其中一个,或者两者都不使用?

假设值是一个常量,第一个选项是最容易理解的,并且在没有Spring的情况下也能工作,从而简化了单元测试。

第二个和第四个选项更为复杂,并且引入了对Spring容器的不必要依赖,没有任何好处。

第三个选项非常奇怪,因为您使用的是@Autowired,而不是执行依赖项注入。

我相信spring提供了所有这些选项,因为您可能会遇到不同的需求。。。

  1. 如果你想要MAX_INT,而实际上没有任何人需要以不同的方式初始化它,那么不管Spring如何,只要声明int field = Integer.MAX_INT就足够了。

  2. 如果您确实希望允许其他初始配置,那么您可以使用@Autowired或通过构造函数arg或setter/getter对其进行初始化。。。这是个品味问题。

  3. @PostConstruct更适合复杂的情况,例如,如果您的字段需要基于其他注入字段进行计算。

相关内容

  • 没有找到相关文章

最新更新