Java 如何使用多个上下文获取Spring到autowire集成测试类?

Java 如何使用多个上下文获取Spring到autowire集成测试类?,java,spring,junit,Java,Spring,Junit,我的一个集成测试使用多个Spring上下文文件。Spring似乎只从第一个上下文而不是第二个上下文自动连接bean。有人知道我做错了什么,或者如何解决这个问题吗 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/META-INF/spring/applicationContext.xml", "classpath:/META-INF/spr

我的一个集成测试使用多个Spring上下文文件。Spring似乎只从第一个上下文而不是第二个上下文自动连接bean。有人知道我做错了什么,或者如何解决这个问题吗

@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = { "classpath:/META-INF/spring/applicationContext.xml", "classpath:/META-INF/spring/applicationContext-security.xml"}) @Configurable public class UserDetailsServiceImplIntegrationTest { @Autowired UserDataOnDemand dod; // @Autowired does not work for this bean from applicationContext-security.xml UserDetailsService userDetailsService; @Before public void setup() { dod.init(); // workaround for autowiring problem userDetailsService = (UserDetailsService)ctx.getBean("userDetailsService"); } @Test public void testLoadUser() { UserDetails ud = userDetailsService.loadUserByUsername("david@somewhere.co.za"); Assert.assertEquals("david@somewhere.co.za", ud.getUsername()); } } @RunWith(SpringJUnit4ClassRunner.class) @上下文配置(位置={ “classpath:/META-INF/spring/applicationContext.xml”, “classpath:/META-INF/spring/applicationContext security.xml”}) @可配置 公共类UserDetailsServiceImpleIntegrationTest{ @自动连线 用户数据与国防部; //@Autowired不适用于applicationContext-security.xml中的此bean 用户详细信息服务用户详细信息服务; @以前 公共作废设置(){ dod.init(); //自动布线问题的解决方法 userDetailsService=(userDetailsService)ctx.getBean(“userDetailsService”); } @试验 public void testLoadUser(){ UserDetails ud=userDetailsService.loadUserByUsername(“david@somewhere.co.za"); Assert.assertEquals(“david@somewhere.co.za,ud.getUsername()); } } 我正在使用Spring3.0.3

以下是我为UserDetailsService取消注释@Autowired行时的堆栈跟踪:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'za.co.acme.app.security.UserDetailsServiceImplIntegrationTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: org.springframework.security.core.userdetails.UserDetailsService za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.userDetailsService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [org.springframework.security.core.userdetails.UserDetailsService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374) at org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:140) at org.springframework.beans.factory.aspectj.AnnotationBeanConfigurerAspect.configureBean(AnnotationBeanConfigurerAspect.aj:59) at org.springframework.beans.factory.aspectj.AbstractDependencyInjectionAspect.ajc$afterReturning$org_springframework_beans_factory_aspectj_AbstractDependencyInjectionAspect$2$1ea6722c(AbstractDependencyInjectionAspect.aj:89) at za.co.acme.app.security.UserDetailsServiceImplIntegrationTest.(UserDetailsServiceImplIntegrationTest.java:25) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:202) org.springframework.beans.factory.BeanCreationException:创建名为“za.co.acme.app.security.UserDetailsServiceImpleIntegrationTest”的bean时出错:自动连线依赖项的注入失败;嵌套异常为org.springframework.beans.factory.BeanCreationException:无法自动连接字段:org.springframework.security.core.userdetails.userdetails服务za.co.acme.app.security.userdetails服务implicationtest.userdetails服务;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到依赖项类型为[org.springframework.security.core.userdetails.UserDetailsService]的匹配bean:应至少有1个符合此依赖项autowire候选项条件的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true)} 位于org.springframework.beans.factory.annotation.AutoWiredNotationBeanPostProcessor.postProcessPropertyValues(AutoWiredNotationBeanPostProcessor.java:286) 位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064) 位于org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374) 位于org.springframework.beans.factory.wiring.BeanConfigurerSupport.configureBean(BeanConfigurerSupport.java:140) 位于org.springframework.beans.factory.aspectj.annotationBeanConfigureSpect.configureBean(annotationBeanConfigureSpect.aj:59) 返回$org\u springframework\u beans\u factory\aspectj.AbstractDependencyInjectionSpect.ajc$后返回$org\u springframework\u beans\u factory\u AbstractDependencyInjectionSpect$2$1ea6722c(AbstractDependencyInjectionSpect.aj:89) 位于za.co.acme.app.security.UserDetailsServiceImpleIntegrationTest。(UserDetailsServiceImpleIntegrationTest.java:25) 位于sun.reflect.NativeConstructorAccessorImpl.newInstance0(本机方法) 位于sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 位于java.lang.reflect.Constructor.newInstance(Constructor.java:513) 位于org.junit.runners.BlockJUnit4ClassRunner.createTest(BlockJUnit4ClassRunner.java:202)
bean肯定在那里,因为“按名称”查找工作正常,并且类型正确。

在xml中,
userDetailsService
的bean名称是什么?您可能需要添加一个带有bean名称的
@Qualifier
注释,然后在上下文中放置一个
标记


看看这个主题。

一个解决方法是创建一个新的单一配置文件(我们称之为“test configuration.xml”),其中包括applicationContext.xml和applicationContext-security.xml。然后您可以在测试中使用这些配置

test-configuration.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <import resource="classpath:/META-INF/spring/applicationContext.xml"/>
    <import resource="classpath:/META-INF/spring/applicationContext-security.xml"/>
</beans>

我有一个类似的设置,它的工作对我来说很好

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext-struts.xml", "classpath:/applicationContext.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public abstract class BaseTests {

我猜问题出在项目的设置上。你使用Eclipse吗?它是从/bin文件夹还是从/src文件夹加载上下文文件?您是否从构建中排除了“applicationContext security.xml”?

您需要告诉Spring对这些注释进行操作。在相关上下文文件中,应添加以下内容:

<context:annotation-config/>

现在它将扫描这些注释。请参阅上的Spring文档

要限制需要扫描的类的数量,以便您不必在没有自动连线的情况下不必要地扫描包,请添加以下内容:

<context:component-scan base-package="org.example"/>


有关这方面的更多信息,请参阅文档,以及您需要添加以引用这些标记的XML名称空间。

我也有同样的问题。似乎存在代理UserDataOnDemand而不是真正的UserDataOnDemand。

我也有同样的问题,解决方案修复了我的问题是通过接口切换bean expose。(即)引用Bean类型应该是接口,而不是其实现类

在您的情况下,使用接口更改具体类
UserDetailsService
引用

例如:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml",
        "classpath:/META-INF/spring/applicationContext-security.xml"})
@Configurable
public class UserDetailsServiceImplIntegrationTest {

  //modified code  
  @Autowired
  IUserDetailsService userDetailsService;

    //your test cases follows

}

注意:我知道这不是一个明智的解决方案,但试一试,我很担心同样的错误,最后改变了我的参考,效果很好。希望它能解决您的问题。

我确实尝试过,也尝试过使用@Resource,但运气不佳。我只有一个UserDetailsService bean,所以按类型划分也应该可以。错误消息表明找不到具有正确类型的bean
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
        "classpath:/META-INF/spring/applicationContext.xml",
        "classpath:/META-INF/spring/applicationContext-security.xml"})
@Configurable
public class UserDetailsServiceImplIntegrationTest {

  //modified code  
  @Autowired
  IUserDetailsService userDetailsService;

    //your test cases follows

}