自动装配时,Spring集成测试速度很慢

Tih*_*hom 19 java spring unit-testing autowired

我正在尝试加速我们环境中的集成测试.我们所有的课程都是自动装配的.在我们的applicationContext.xml文件中,我们定义了以下内容:

<context:annotation-config/>
<context:component-scan base-package="com.mycompany.framework"/>
<context:component-scan base-package="com.mycompany.service"/>
...additional directories
Run Code Online (Sandbox Code Playgroud)

我注意到Spring正在扫描上面指出的所有目录,然后迭代每个bean并缓存每个bean的属性.(我从春天开始查看DEBUG消息)

因此,以下测试大约需要14秒才能运行:

public class MyTest extends BaseSpringTest {
  @Test
  def void myTest(){
    println "test"
  }
}
Run Code Online (Sandbox Code Playgroud)

有没有办法延迟加载配置?我尝试添加default-lazy-init="true"但是没有用.

理想情况下,只实例化测试所需的bean.

提前致谢.

更新:我之前应该说过,我不想为每个测试都有一个上下文文件.我也不认为只有测试的一个上下文文件才有效.(此测试上下文文件最终会包含所有内容)

Art*_*ald 16

如果您确实想要加速应用程序上下文,请在运行任何测试之前禁用<component-scan并执行以下例程

Resource resource = new ClassPathResource(<PUT_XML_PATH_RIGHT_HERE>); // source.xml, for instance
InputStream in = resource.getInputStream();

Document document = new SAXReader().read(in);
Element root  = document.getRootElement();

/**
  * remove component-scanning
  */
for ( Iterator i = root.elementIterator(); i.hasNext(); ) {
    Element element = (Element) i.next();

    if(element.getNamespacePrefix().equals("context") && element.getName().equals("component-scan"))
        root.remove(element);
}

in.close();

ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(true);
for (String source: new String[] {"com.mycompany.framework", "com.mycompany.service"}) {
    for (BeanDefinition bd: scanner.findCandidateComponents(source)) {
        root
        .addElement("bean")
        .addAttribute("class", bd.getBeanClassName());
    }
}

//add attribute default-lazy-init = true
root.addAttribute("default-lazy-init","true");

/**
  * creates a new xml file which will be used for testing
  */ 
XMLWriter output = new XMLWriter(new FileWriter(<SET_UP_DESTINATION_RIGHT_HERE>));
output.write(document);
output.close(); 
Run Code Online (Sandbox Code Playgroud)

除此之外,启用<context:annotation-config />

由于在运行任何测试之前需要执行上述例程,因此可以创建一个抽象类,您可以在其中运行以下命令

设置用于测试环境的Java系统属性,如下所示

-Doptimized-application-context=false
Run Code Online (Sandbox Code Playgroud)

public abstract class Initializer {

    @BeforeClass
    public static void setUpOptimizedApplicationContextFile() {
        if(System.getProperty("optimized-application-context").equals("false")) {
            // do as shown above

            // and

            System.setProperty("optimized-application-context", "true"); 
        }

    }

}
Run Code Online (Sandbox Code Playgroud)

现在,对于每个测试类,只需扩展Initializer


ska*_*man 1

这是自动检测组件所付出的代价——速度较慢。尽管您的测试只需要某些 bean,但您的测试范围<context:component-scan>要广泛得多,Spring 将实例化并初始化它找到的每个 bean。

我建议您在测试中使用不同的 beans 文件,该文件仅定义测试本身所需的 beans,即不使用<context:component-scan>.