我有一个在this github上托管的开源项目。我面临一个奇怪的场景。我发现许多人可以使@Autowired Spring注释在他们的主类上工作,但不能在他们的JUnit测试类上工作。我的问题是另一种方式。我可以在我的JUnit测试类中成功使用@Autowired,但是当测试调用我的主类时,依赖关系不会被注入。这是我的上下文(简化版):
登录类:
package net.openrally.restaurant.core.exposure.resource;
@Path("/login")
@Component
@Transactional
@Singleton
@Produces("application/json")
@Consumes("application/json")
public class Login extends BaseResource{
@Autowired
private UserDAO userDAO;
@POST
public Response post(String requestBody){
...
//NullPointerException
User user = userDAO.loadByCompanyIdAndLogin(companyId, login);
}
...
}
LoginTest Class:
package net.openrally.restaurant.core.exposure.resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/applicationContext.xml")
public class LoginTest extends BaseResourceTest {
@Autowired
private UserDAO userDAO;
...
@Test
public void testInvalidPassword() {
....
// Works perfectly!
userDAO.save(user);
....
}
}
的applicationContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:configuration.properties</value>
</list>
</property>
</bean>
<context:annotation-config />
<context:component-scan base-package="net.openrally.restaurant.core" />
<import resource="db-config.xml" />
</beans>
我正在寻找解决方案几天了。从我到目前为止发现的情况来看,大多数@Autowired
个问题的人在他们的spring xml中没有<context:annotation-config />
或xmlns:context="http://www.springframework.org/schema/context"
或者没有@Component
家族注释他们希望DI发生的类,正如你所看到的,他们都在那里:(。我的项目中只有一个applicationContext.xml
适合运行时和测试(我有不同的configuration.properties来设置数据库凭据和日志级别不同,但没有弹簧配置)
我正在使用:
Spring: 3.1.0.RELEASE
JUnit: 4.10
Jersey: 1.11
CLIB: 2.2.2
任何想法,我的意思是任何:),非常感谢。
更新
运行测试时会出现以下日志:
2012-03-27 07:37:02,457 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'login'
2012-03-27 07:37:02,457 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating instance of bean 'login'
2012-03-27 07:37:02,459 DEBUG [main] org.springframework.beans.factory.annotation.InjectionMetadata - Found injected element on class [net.openrally.restaurant.core.exposure.resource.Login]: AutowiredFieldElement for private net.openrally.restaurant.core.persistence.dao.ConfigurationDAO net.openrally.restaurant.core.exposure.resource.Login.configurationDAO
2012-03-27 07:37:02,459 DEBUG [main] org.springframework.beans.factory.annotation.InjectionMetadata - Found injected element on class [net.openrally.restaurant.core.exposure.resource.Login]: AutowiredFieldElement for private net.openrally.restaurant.core.persistence.dao.UserDAO net.openrally.restaurant.core.exposure.resource.Login.userDAO
2012-03-27 07:37:02,459 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'login' to allow for resolving potential circular references
2012-03-27 07:37:02,459 TRACE [main] org.springframework.beans.CachedIntrospectionResults - Getting BeanInfo for class [net.openrally.restaurant.core.exposure.resource.Login]
2012-03-27 07:37:02,462 TRACE [main] org.springframework.beans.CachedIntrospectionResults - Caching PropertyDescriptors for class [net.openrally.restaurant.core.exposure.resource.Login]
2012-03-27 07:37:02,462 TRACE [main] org.springframework.beans.CachedIntrospectionResults - Found bean property 'class' of type [java.lang.Class]
2012-03-27 07:37:02,462 DEBUG [main] org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'login': AutowiredFieldElement for private net.openrally.restaurant.core.persistence.dao.ConfigurationDAO net.openrally.restaurant.core.exposure.resource.Login.configurationDAO
2012-03-27 07:37:02,462 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'configurationDAO'
2012-03-27 07:37:02,462 DEBUG [main] org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - Autowiring by type from bean name 'login' to bean named 'configurationDAO'
2012-03-27 07:37:02,463 DEBUG [main] org.springframework.beans.factory.annotation.InjectionMetadata - Processing injected method of bean 'login': AutowiredFieldElement for private net.openrally.restaurant.core.persistence.dao.UserDAO net.openrally.restaurant.core.exposure.resource.Login.userDAO
2012-03-27 07:37:02,463 DEBUG [main] org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'userDAO'
2012-03-27 07:37:02,463 DEBUG [main] org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor - Autowiring by type from bean name 'login' to bean named 'userDAO'
2012-03-27 07:37:02,464 DEBUG [main] org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator - Creating implicit proxy for bean 'login' with 0 common interceptors and 1 specific interceptors
2012-03-27 07:37:02,464 DEBUG [main] org.springframework.aop.framework.Cglib2AopProxy - Creating CGLIB2 proxy: target source is SingletonTargetSource for target object [net.openrally.restaurant.core.exposure.resource.Login@60532a0a]
2012-03-27 07:37:02,465 DEBUG [main] org.springframework.aop.framework.Cglib2AopProxy - Unable to apply any optimisations to advised method: public javax.ws.rs.core.Response net.openrally.restaurant.core.exposure.resource.Login.post(java.lang.String)
Spring可以正确创建我的bean但Jersey使用自己的非自动装配实例吗?
答案 0 :(得分:0)
经过一段时间的研究,我找不到让GrizzlyWeb使用spring加载的上下文的方法,所以我试图找到另一种解决方案。
然后我找到了Hifaces20,它可以让你在同一个JVM中启动和停止一个jetty实例(这意味着你可以使用一个内存数据库,你的测试和你的应用程序)
答案 1 :(得分:0)
我遇到了完全相同的问题,后来发现这是一个开发人员问题:)
我正在创建一个新对象,而不是使用spring bean。
让我们说班级MyService
自动装配道教班MyDao myDaoBean
。现在假设我想在MyService
中使用MyController
,我应该连接Spring bean myServiceSpringBean
。如果我尝试创建一个新的myServiceObject
,那么Spring不会将myDaoBean
连接到myServiceObject
,因为它不知道该新服务对象。
这导致myDaoBean
为空。