Java 如何让 Spring 使用多个上下文自动装配集成测试类?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3413639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get Spring to autowire integration test class using multiple contexts?
提问by David Tinker
One of my integration tests uses multiple Spring context files. It seems that Spring only autowires in beans from the first context and not the second. Does anyone know what I am doing wrong or how to work around the problem?
我的集成测试之一使用多个 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("[email protected]"); Assert.assertEquals("[email protected]", ud.getUsername()); } }
I am using Spring 3.0.3.
我正在使用 Spring 3.0.3。
Here is the stack trace when I uncomment the @Autowired line for UserDetailsService:
这是我取消注释 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_AbstractDependencyInjectionAspectea6722c(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)
The bean is definitely there since the "by name" lookup works, and it is of the correct type.
bean 肯定存在,因为“按名称”查找有效,并且它的类型正确。
回答by Noel M
What is the name of the bean for userDetailsService
in your xml? You might need to add a @Qualifier
annotation with the bean name, and then putting a <qualifier>
tag in the context.
userDetailsService
你的 xml 中bean 的名称是什么?您可能需要@Qualifier
使用 bean 名称添加注释,然后<qualifier>
在上下文中放置一个标记。
Take a look at Spring's documentationon the topic.
查看有关该主题的Spring 文档。
回答by Ralph
A workaround is to create a new single configuration file (let's call it "test-configuration.xml") which is including the both applicationContext.xml and applicationContext-security.xml. Then you can use these configurations within your tests.
一种解决方法是创建一个新的单个配置文件(我们称之为“test-configuration.xml”),其中包括 applicationContext.xml 和 applicationContext-security.xml。然后您可以在测试中使用这些配置。
test-configuration.xml:
测试配置.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>
UserDetailsServiceImplIntegrationTest.java:
UserDetailsServiceImplIntegrationTest.java:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/test-configuration.xml")
@Configurable
public class UserDetailsServiceImplIntegrationTest {
...
}
回答by Thierry-Dimitri Roy
I have a similar setup and it's working fine for me.
我有一个类似的设置,它对我来说很好用。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:/applicationContext-struts.xml", "classpath:/applicationContext.xml" })
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public abstract class BaseTests {
My guess is that the problem is in the setup of your project. Do you use Eclipse? Does it load the context files from the /bin folder or from a /src folder? Did you exclude "applicationContext-security.xml" from the build?
我的猜测是问题出在您的项目设置中。你使用 Eclipse 吗?它是从 /bin 文件夹还是从 /src 文件夹加载上下文文件?您是否从构建中排除了“applicationContext-security.xml”?
回答by Lyle
You need to tell Spring to act on those annotations. In the relevant context file you should add the following:
您需要告诉 Spring 对这些注释采取行动。在相关的上下文文件中,您应该添加以下内容:
<context:annotation-config/>
Now it'll scan for those annotations. See the Spring documentation on Annotation-based configuration
现在它将扫描这些注释。请参阅有关基于注释的配置的 Spring 文档
To limit the number of classes it needs to scan so you don't needlessly scan packages with no autowiring, add this:
要限制它需要扫描的类的数量,这样您就不会在没有自动装配的情况下不必要地扫描包,请添加以下内容:
<context:component-scan base-package="org.example"/>
See the docs for Auto-detecting componentsfor more on that, as well as the XML namespaces you'll need to add to reference those tags.
有关更多信息,请参阅自动检测组件的文档,以及您需要添加以引用这些标签的 XML 命名空间。
回答by inza9hi
I have the same problems.It seems that there is a proxy UserDataOnDemand instead of the real UserDataOnDemand .
我有同样的问题。似乎有一个代理 UserDataOnDemand 而不是真正的 UserDataOnDemand 。
回答by omega
I had the same problem, the solution fixed my problem is switch the bean expose through Interface. (i.e) Your reference Bean Type should be a Interfaceinstead of its implementation class
我遇到了同样的问题,解决我的问题的解决方案是通过接口切换 bean 公开。(即)你的引用 Bean 类型应该是一个接口而不是它的实现类
In your case change the concrete Class UserDetailsService
reference with its interface.
在您的情况下,UserDetailsService
使用其接口更改具体的 Class引用。
For Example:
例如:
@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
}
NOTE:I know this wont be a sensible solution, But just give a try, I worried lot because of this same error and finally changed my reference and it worked fine. Hope it would resolve your issue.
注意:我知道这不会是一个明智的解决方案,但请尝试一下,由于同样的错误,我很担心,最后更改了我的参考,并且效果很好。希望它能解决您的问题。