2012-03-27 3 views
1

У меня есть проект с открытым исходным кодом, размещенный в this github. Я столкнулся с странным сценарием. Я нашел много людей, которые могли бы использовать аннотацию @Autowired Spring для своих основных классов, но не на своих тестовых классах JUnit. Моя проблема - наоборот. Я могу успешно использовать @Autowired в моем тестовом классе JUnit, но когда тест вызывает мой основной класс, зависимости не вводятся туда. Вот мой контекст (упрощенная версия):Spring @Autowired OK на JUnit, NPE по основному классу

Войти Класс:

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 Класс:

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, не имеют <context:annotation-config /> или xmlns:context="http://www.springframework.org/schema/context" в их весеннем xml или не имеют семейной аннотации @Component в классе, который они хотят провести DI, и, как вы можете видеть, они я имею только один :(У меня есть только один applicationContext.xml в моем проекте, который подходит как для времени выполнения, так и для теста (у меня есть разные параметры конфигурации. Устанавливать учетные данные и уровни регистрации по-разному, но нет конфигурации пружины там)

Я используя:

Spring: 3.1.0.RELEASE 
JUnit: 4.10 
Jersey: 1.11 
CLIB: 2.2.2 

Любые идеи, а я имею в виду ЛЮБОЙ :), очень ценится.

UPDATE

следующие журналы придумал, когда я запускаю тест:

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 [[email protected]] 
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) 

Может весной создавать свой боб правильно, но Джерси, используя свой собственный, не autowired экземпляр?

+0

Существует ли какой-либо конфликт между '@ Component' и' @ Singleton' на вашем компоненте? И как загружается файл 'applicationContext.xml' для среды выполнения? –

+0

Здравствуйте, nico_ekito, спасибо за ваш вклад. «@ Singleton» - это просто оптимизация. Я попытался удалить его после вашего комментария, но не повезло ... «appliationContext.xml» находится в папке ресурсов, а проект имеет весенние зависимости, управляемые maven. Я планирую использовать причал как веб-контейнер, но для тестов я использую Grizzly Web Container из Джерси. – robertobado

+0

Но как ваш файл 'applicationContext.xml' загружается в ваше приложение времени исполнения? Под «ClassPathXmlApplicationContext»? С помощью webapp? –

ответ

0

После некоторого исследования я не смог найти способ заставить GrizzlyWeb использовать контекст, загруженный весной, поэтому я попытался найти альтернативное решение.

Я тогда нашел Hifaces20, который позволит запускать и останавливать экземпляр причалу в пределах одной и той же виртуальной машины Java (что означает, что вы можете, например, использовать базу данных памяти, которая будет рассматриваться как тестами и приложения)

0

У меня была одна и та же проблема, и позже выяснилось, что это была проблема с разработчиком :)

Я создавал новый объект вместо использования весеннего боба.

Скажем, класс MyService autowires dao class MyDao myDaoBean. Теперь позвольте сказать, что я хочу использовать MyService в MyController, я должен проложить весной фасоль myServiceSpringBean. Если я попытаюсь создать новый myServiceObject, то Spring не подключит myDaoBean к myServiceObject, потому что он не знает об этом новом объекте службы.

И это приводит к myDaoBean, являющемуся нулем.

Смежные вопросы