如何使用new Condition接口从Spring中排除一个类



我们经常有不同的测试和生产环境。根据某些配置参数,容器不需要将某些类注册为bean(在使用spring时)。是否有一种方法可以从应用程序上下文中动态跳过这些类?

如果应该在测试中使用的类只能在测试时的类路径中可用,并且您的问题是关于替换注入的类,那么您可以用@Primary注释在TESTs中使用的类。

@Primary是spring的一个特性,它比条件要老得多,功能也不那么强大,但它确实很容易使用。是说:什么时候有注射点可以用两个bean来完成,然后使用用@Primary注释的bean,而不是抛出一个异常来抱怨有歧义的bean。

因此,当您在测试范围中添加带有@Primary注释的bean时,该bean将替换其注入点中的原始bean。

使用Spring 4 @条件注释,我们可以。

查看此处查看Spring Condition界面的详细信息

首先创建一个类,比如- "ComponentScanCondition ",它实现了Spring的"Condition"接口。如果系统属性不为空或者是"测试"环境,唯一的方法"matches"返回false。

public class ComponentScanCondition implements Condition{
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metaData) {
    return System.getProperty("environment")!=null && System.getProperty("environment").equals("test")? false:true;
}

}

现在有了注释- @Conditional(ComponentScanCondition.class),你可以控制测试环境中不需要的类的组件扫描。

在jUnit测试类中,设置一个系统属性,如下所示:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class testMyClass{
 @BeforeClass
 public static void setUpBeforeClass() throws Exception{
  System.setProperty("environment", "test");
 }
 @Test
 public void testSomeMethod(){
 }

}

在测试中不需要的类中,使用@条件注释。例如,如果您在测试环境中不需要UserProfile类,则跳过它,如下所示:

@service("userProfile")
@Conditional(ComponentScanCondition.class)
public class UserProfile{
}

在测试类中,系统属性"environment"被设置为"test", match方法将返回false, Spring将跳过要扫描的UserProfile类。

在prod环境中,该属性将不设置,将为null,因此匹配将返回true,因此UserProfile(和那些带有@Conditional的类)将被Spring扫描以注册为容器中的bean。

最新更新