繁体   English   中英

有没有办法防止 Spring 中的配置依赖注入?

[英]Is there a way to prevent dependency injection from config in Spring?

我正在开发一个 Spring 项目,其中单元测试有自己的名为 UnitTestConfig 的配置,它定义了几个类似于主应用程序文件(几乎是副本)的 bean。 保持结构不变,我对主应用程序服务器代码进行了一些更改,但是这会在 UnitTestConfig 中引发错误,因为它没有注入所需的 bean。 这些 bean 不在单元测试中使用,有没有办法阻止 UnitTestConfig 尝试注入它们? 这是一个很大的级联效应,因为 A 注入,B 注入 C,依此类推,它期待所有这些 Bean。 有什么办法可以告诉 Spring 配置我不想注入这些 bean 或将它们设为 null 吗?

@Configuration
public class UnitTestConfig {

    @Inject
    private Environment env;

    @Bean
    public A a() {
        return new A();
    }

为了在需要时不注入 A 的字段,我在字段上添加了一个 @Lazy 并且它似乎有效,但我希望对此进行任何修改都在测试配置方面,而不是修改主应用程序代码只是为了修复测试问题。 有什么建议?

这是大多数应用程序的一个非常普遍的问题,随着应用程序的增长,添加具有通用配置的单元测试变得困难。 运行单元测试变成了一场噩梦,因为您必须处理不必要的上下文加载。

我们最终开始拥有测试配置文件,以解决加载不必要的 bean 的问题。 并且仅为某些配置文件加载 bean。 像这样的东西——

如何禁用在 Spring 中使用 @Component 注释创建 bean?

但这会产生它自己的问题 - 创建多个配置文件和管理这些配置文件。 如果管理配置文件不是问题,这可以帮助您。

或者,我们停止使用公共上下文进行单元测试,并开始使用静态测试上下文类隔离测试类并模拟所有非必需 bean。 像这样的东西——

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class SomeJavaClassTest {

    @Autowired
    private Bean1 bean1;
    @Autowired
    private Bean2 bean2;
    @Autowired
    private Bean3 bean3;
    
    @test
    public void method1Test() throws Exception {
    }
    
    @test
    public void method2Test() throws Exception {
    }
    
    @Configuration
    static class Config {
    
        @Bean
        public Bean1 bean1() {
            return Mockito.mock(Bean1.class);
        }

        @Bean
        public Bean2 bean2() {
            return new SomeJavaClass();
        }
        
        @Bean
        public Bean3 bean3() {
            return Mockito.mock(Bean3.class);
        }
    
        @Bean
        public PropertySourcesPlaceholderConfigurer properties() throws Exception {
            PropertySourcesPlaceholderConfigurer propertyPlaceholder = new PropertySourcesPlaceholderConfigurer();

            // setup properties that needs to be injected into the class under test

            Properties properties = new Properties();
            properties.setProperty("some.required.properties", "");
            
            propertyPlaceholder.setProperties(properties);

            return propertyPlaceholder;
    }
}

这称为循环 bean 依赖。 有很多方法可以解决这个问题。 在构造函数参数中使用@Lazy 进行注释。 代替构造函数注入器使用 setter 注入或在 application.properties 文件中写入 spring.main.allow-bean-definition-overriding=true

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM