如果设置@Enableconfigurationproperties,为什么@Contexthierarchy不缓存bean?

时间:2018-02-27 17:30:28

标签: java spring

我决定在没有“@SpringBootTest”的情况下编写“组件”测试。如果设置@Enableconfigurationproperties,@Сontexthierarchy不会缓存bean。

当我同时运行“TestOne”和“TestTwo”时,HelloWorld组件被初始化两次,这可以通过“init666”中字符串的双重外观来证明。可能是什么问题?

TestOne

@RunWith(SpringRunner.class)
@EnableConfigurationProperties
@ContextHierarchy({
        @ContextConfiguration(classes = TestConfiguration.class),
        @ContextConfiguration(classes = TestOneConfiguration.class)
})
public class TestOne {

    @Autowired
    HelloWorld helloWorld;

    @Test
    public void test () {

    }

}

TestOneConfiguration

@Configuration
public class TestOneConfiguration {
}

TestTwo

@RunWith(SpringRunner.class)
@EnableConfigurationProperties
@ContextHierarchy({
        @ContextConfiguration(classes = TestConfiguration.class),
        @ContextConfiguration(classes = TestTwoConfiguration.class)
})
public class TestTwo {

    @Autowired
    HelloWorld helloWorld;

    @Test
    public void test () {

    }
}

TestTwoConfiguration

@Configuration
public class TestTwoConfiguration {
}

TestConfiguration

@Configuration
public class TestConfiguration {

    @Bean
    HelloWorld helloWorld () {
        return new HelloWorld();
    }

HelloWorld

@Component

    public class HelloWorld {
        public HelloWorld() {
            System.out.println("init666");
        }
    }

屏幕截图double appearance of the string in "init666"

P.S。 @SpringBootTest无法使用

1 个答案:

答案 0 :(得分:1)

目前我找到了唯一的解决方案:

摆脱@Enableconfigurationproperties

从application.yml加载属性

<强> TestOne

@RunWith(SpringRunner.class)
@EnableConfigurationProperties
@ContextHierarchy({
        @ContextConfiguration(classes = TestConfiguration.class,
                       initializers = TestContextInitializer.class),
        @ContextConfiguration(classes = TestOneConfiguration.class)
})

public class TestOne {

    @Autowired
    HelloWorld helloWorld;

    @Test
    public void test () {

    }
}

<强> TestContextInitializer

public class TestContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        try {
            Resource resource = applicationContext.getResource("classpath:application.yml");
            YamlPropertySourceLoader sourceLoader = new YamlPropertySourceLoader();
            PropertySource<?> yamlTestProperties = sourceLoader.load("applicationProperties", resource, null);
            applicationContext.getEnvironment().getPropertySources().addFirst(yamlTestProperties);
            String[] profiles = applicationContext.getEnvironment().getProperty("spring.profiles.active").replaceAll(" ", "").split(",");
            applicationContext.getEnvironment().setActiveProfiles(profiles);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

通过Enviroment

填写必填字段
@Autowired
private Environment environment; 

public Someclass somemethod() {
    Someclass someclass = new Someclass();
    String someField = environment.getProperty("someField");
    someclass.setSomeField(someField);
    return someclass;
}

如果有更好的事情,我会很高兴看到这些建议 谢谢!