Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Spring集成测试期间刷新/重建特定bean_Java_Spring_Spring Boot_Junit_Integration Testing - Fatal编程技术网

Java 在Spring集成测试期间刷新/重建特定bean

Java 在Spring集成测试期间刷新/重建特定bean,java,spring,spring-boot,junit,integration-testing,Java,Spring,Spring Boot,Junit,Integration Testing,我们现有的Spring Boot集成设置使用@DirtiesContext在不同的测试方法之间重建整个bean池 这相当缓慢,因此我们开始使用可以“刷新”或内部拆除/重建的bean,而无需重新创建实例 问题是只有一些bean支持这一点。如果我们控制UsersBean,我们可以实现UsersBean.refresh()方法,并在@After方法中调用它 但是,如果我们现有的bean/类不支持刷新,或者我们不进行控制,那么我们如何有条件地指示某些bean需要在特定测试之后被弄脏/重建呢 或者更简洁地

我们现有的Spring Boot集成设置使用
@DirtiesContext
在不同的测试方法之间重建整个bean池

这相当缓慢,因此我们开始使用可以“刷新”或内部拆除/重建的bean,而无需重新创建实例

问题是只有一些bean支持这一点。如果我们控制
UsersBean
,我们可以实现
UsersBean.refresh()
方法,并在
@After
方法中调用它

但是,如果我们现有的bean/类不支持刷新,或者我们不进行控制,那么我们如何有条件地指示某些bean需要在特定测试之后被弄脏/重建呢


或者更简洁地说:有没有一种方法可以在测试方法结束时将bean池的一部分标记为脏的,以便重新构建?

看起来这是可能的,至少在Spring引导环境中是可能的。
ApplicationContext
实现有一个功能,可以通过重新注册

这甚至可以通过级联来删除包含对正在删除的bean的引用的bean(可以在中看到它的实现)

例如,如果
Bean1
Bean2
引用:

@Component
public class Bean1 {

}

@Component
public class Bean2 {
    @Autowired
    public Bean1 bean1;
}
然后,测试可以从上下文中删除
bean1
,也可以查看
bean2
替换:

@RunWith(SpringRunner.class)
public class BeanRemovalTest implements ApplicationContextAware {
    @Autowired
    private Bean1 bean1;

    @Autowired
    private Bean2 bean2;

    private ApplicationContext applicationContext;

    @Test
    public void test1() throws Exception {
        System.out.println("test1():");
        System.out.println("  bean1=" + bean1);
        System.out.println("  bean2.bean1=" + bean2.bean1);

        resetBean("bean1");
    }

    @Test
    public void test2() throws Exception {
        System.out.println("test2():");
        System.out.println("  bean1=" + bean1);
        System.out.println("  bean2.bean1=" + bean2.bean1);
    }

    private void resetBean(String beanName) {
        GenericApplicationContext genericApplicationContext = (GenericApplicationContext) applicationContext;
        BeanDefinition bd = genericApplicationContext
                .getBeanDefinition(beanName);
        genericApplicationContext.removeBeanDefinition("bean1");
        genericApplicationContext.registerBeanDefinition("bean1", bd);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.applicationContext = applicationContext;
    }
}
这显示了两个被替换的bean实例:

test1():
  bean1=hello.so.Bean1@61d6015a
  bean2.bean1=hello.so.Bean1@61d6015a

test2():
  bean1=hello.so.Bean1@2e570ded
  bean2.bean1=hello.so.Bean1@2e570ded
(如果
resetBean(“bean1”)
被注释掉,那么它在两次循环中都是相同的实例)


肯定会有一些边不起作用-例如,如果另一个bean持有从
ApplicationContext.getBean()获取的引用,谢谢,这看起来很完美。我会测试一下,19小时后我可以给你奖金。