【问题标题】:Spring Boot Java Config - split web (controllers, etc), and servicesSpring Boot Java Config - 拆分 Web(控制器等)和服务
【发布时间】:2014-10-23 22:42:26
【问题描述】:

在我的旧 XML 配置项目中,我可以在我的配置中执行以下操作

mvc-context.xml

<context:component-scan base-package="com.foo" use-default-filters="false">
    <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

<mvc:annotation-driven/>

service-context.xml

<context:spring-configured />
<context:annotation-config />

<context:component-scan base-package="com.foo" >
    <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
</context:component-scan>

在我的测试中,我可以执行以下操作

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextHierarchy(value = {
    @ContextConfiguration(classes = { MockServices.class }),
    @ContextConfiguration({ "classpath:/META-INF/spring/mvc-servlet-context.xml" }),
})
public class FooControllerTest {
    @Autowired
    private WebApplicationContext wac;

    private MockMvc mvc;

    @Before
    public void setUp() throws Exception {
        mvc = webAppContextSetup(wac).build();
    }
}

然后我可以针对我的 MVC 配置运行测试,而无需加载我的服务和 JPA 存储库,而是将我的模拟 @Autowired 放入我的控制器中。

但是,Spring Boot 应用程序在主上下文配置中有以下内容

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
}

这个@ComponentScan 显然可以找到所有@Controller@Service

如果我现在尝试测试我的 MVC 上下文,我会加载不需要的服务和存储库。

我试图做的是创建 2 个新配置

Mvc.java

@Configuration
@ComponentScan(basePackages = { "com.foo" }, useDefaultFilters = false, includeFilters = {@Filter(value = org.springframework.stereotype.Controller.class)} )
@Order(2)
public class Mvc {
}

Services.java

@Configuration
@ComponentScan(basePackages = { "com.foo" }, useDefaultFilters = false, excludeFilters = {@Filter(value = org.springframework.stereotype.Controller.class)} )
@Order(1)
public class Services {
}

但这不起作用,当我尝试启动我的应用程序时,我会收到@Autowire 错误No qualifying bean of type

我是不是走错了路?

如何做到这一点,以便我可以在我的 MVC 上下文上运行测试,而不会因加载 JPA EntityManager、Spring 数据存储库等而浪费时间?

【问题讨论】:

  • 能否请您输入堆栈错误以便我们进行故障排除
  • 你复制粘贴太多了。从 Services 类中删除 useDefaultFilters 属性。如果您只想测试一个控制器,您是否真的需要上下文,只需自己创建一个实例并模拟单元测试中所需的服务和/或使用 Spring Test MockMVC 来测试您的控制器。
  • 不确定复制粘贴与任何事情有什么关系,肯定没有useDefaultFiltersexcludeFilters 控制器将被加载两次?使用MockMvcBuilders.standaloneSetup 可以,除了它不包括MVC 使用的所有其他东西,例如ControllerAdviceExceptionResolversConversionServices 等。这就是我想使用MockMvcBuilders.webAppContextSetup 的原因。我已经更新了上面的代码以显示

标签: spring spring-mvc spring-boot spring-test-mvc


【解决方案1】:

M. Deinum 在 cmets 中给出的解决方案是正确的,但可能是您没有得到提示。 当你说: useDefaultFilters = falseexcludeFilters = {@Filter(value = org.springframework.stereotype.Controller.class)} 什么都找不到,因为useDefaultFilters = false 会阻止spring 寻找像@Controller, @Service ... 这样的原型注解

Link to Spring API doc

【讨论】:

  • 在阅读了ComponentScanAnnotationParser 的源代码之后,这确实是有道理的。我想知道我的 xml 配置实际上是如何工作的,因为它还包括 useDefaultFilter=falseexcludeFilters
猜你喜欢
  • 1970-01-01
  • 2015-05-14
  • 2015-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多