8

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

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

import org.springframework.stereotype.Component;

@Component
public class DeclarationInit {

    private final int field = Integer.MAX_VALUE;

    public int getField() {
        return field;
    }
}

@Value2.使用注解初始化字段

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

@Autowired3.使用注解初始化字段

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

@PostConstruct4.使用注解初始化字段

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

这些声明是否彼此相等,或者我应该只使用其中一个还是不使用它们?

4

2 回答 2

7

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

第二个和第四个选项更复杂,并且引入了对 Spring 容器的不必要的依赖,没有任何好处。第三个选项非常奇怪,因为您正在使用@Autowired而不是执行依赖注入。

于 2015-11-18T10:38:21.907 回答
2

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

  1. 如果你想要MAX_INT并且地球上没有人需要以不同的方式初始化它,那么int field = Integer.MAX_INT无论 Spring 声明如何就足够了。

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

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

于 2015-11-18T11:24:15.010 回答