2011-01-27 10 views
8

Próba skonfigurowania projektu, ale nie powiedzie się w Autowiring obiektów przez Spring.@Aktualizowane obiekty otrzymujące wartość pustą

package se.hsr.web; 

public class TestRunner { 

    public static void main(String[] args) { 
     ContactDAO cd = new ContactDAOImpl(); 
     Contact contact = new Contact(); 
     contact.setFirstname("Zorro"); 
     cd.addContact(contact); 
    } 

} 

package se.hsr.web; 

Running to daje mi NullPointerException podczas cd.addContact jest wywoływany. ContactDaoImpl:

import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Repository; 

@Repository 
public class ContactDAOImpl implements ContactDAO { 

    @Autowired 
    private SessionFactory sessionFactory; 

    public void addContact(Contact contact) { 
     sessionFactory.getCurrentSession().save(contact); 
    } 

Mój plik servlet:

<?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:p="http://www.springframework.org/schema/p" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    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"> 

    <context:component-scan 
     base-package="se.hsr.web"/> 

    <bean id="viewResolver" 
     class="org.springframework.web.servlet.view.UrlBasedViewResolver"> 
     <property name="viewClass" 
      value="org.springframework.web.servlet.view.JstlView" /> 
     <property name="prefix" value="/WEB-INF/jsp/" /> 
     <property name="suffix" value=".jsp" /> 
    </bean> 

    <bean id="propertyConfigurer" 
     class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" 
     p:location="/WEB-INF/jdbc.properties" /> 

    <bean id="dataSource" 
     class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" 
     p:driverClassName="${jdbc.driverClassName}" 
     p:url="${jdbc.databaseurl}" p:username="${jdbc.username}" 
     p:password="${jdbc.password}" /> 

    <bean id="sessionFactory" 
     class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource" /> 
     <property name="configLocation"> 
      <value>classpath:hibernate.cfg.xml</value> 
     </property> 
     <property name="configurationClass"> 
      <value>org.hibernate.cfg.AnnotationConfiguration</value> 
     </property> 
     <property name="hibernateProperties"> 
      <props> 
       <prop key="hibernate.dialect">${jdbc.dialect}</prop> 
       <prop key="hibernate.show_sql">true</prop> 
      </props> 
     </property> 
    </bean> 

    <bean id="contactDAOImpl" 
     class="se.hsr.web.ContactDAOImpl"/> 

    <context:annotation-config/> 

</beans> 

Mój plik hibernate.cfg.xml:

<?xml version='1.0' encoding='utf-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
    "-//Hibernate/Hibernate Configuration DTD//EN" 
    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 

<hibernate-configuration> 
    <session-factory> 
     <mapping class="se.hsr.web.Contact" /> 
    </session-factory> 

</hibernate-configuration> 

Mój plik web.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
    id="WebApp_ID" version="2.5"> 
    <display-name>HSRMVC</display-name> 
    <welcome-file-list> 
     <welcome-file>index.jsp</welcome-file> 
    </welcome-file-list> 

    <servlet> 
     <servlet-name>HSR</servlet-name> 
     <servlet-class> 
      org.springframework.web.servlet.DispatcherServlet 
     </servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 
    <servlet-mapping> 
     <servlet-name>HSR</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 
</web-app> 

Przypuszczam, że błąd jest taki w SessionFactory nie jest inicjalizowany poprawnie przez @Autowired, ale dlaczego tak jest? Czy może to być prosty problem ze strukturą katalogów/plików lub czy jest to coś bardziej skomplikowanego?

Z góry dziękuję.

UPDATE: klasa ContactDAOImpl:

@Repository 
public class ContactDAOImpl extends HibernateDaoSupport implements ContactDAO{ 

    @Autowired 
    @Qualifier("sessionFactory") 
    private SessionFactory sessionFactory; 

    public void addContact(Contact contact) { 
     sessionFactory.getCurrentSession().save(contact); 
    } 
+0

możliwym duplikatu [Dlaczego moje pole Wiosna @Autowired zerowy ?] (http://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null) – chrylis

Odpowiedz

14

Aby skorzystać z funkcji Spring (autowiring, wywołanie, aby opublikować metody lub aspekty konstrukcyjne), musisz pozwolić instancji Spring instancję zamiast używać new.

Na przykład:

public static void main(String[] args) { 
    ApplicationContext context = AnnotationConfigApplicationContext("se.hsr.web") 
    ContactDAO cd = (ContactDAO)context.getBean("contactDAOImpl"); 
    Contact contact = new Contact(); 
    contact.setFirstname("Zorro"); 
    cd.addContact(contact); 
} 

AnnotationConfigApplicationContext skanuje zajęcia w klasach w pakiecie se.hsr.web do klas z adnotacji wiosny. Wymaga Spring 3.0 do pracy.Przedtem należy dodać następującą linię w pliku applicationContext.xml:

<context:component-scan base-package="se.hsr.web" /> 
+0

Wielkie dzięki, ale to nie korzysta z @Autowired adnotacji jest to? Czy istnieje inny sposób, aby to działało za pomocą funkcji autowiring? –

+1

@Emil - Używa @Autowired. Chodzi o to, że zależności są auto- romowane, ale obiekt główny (ContactDao) musi zostać wiosenny, aby to się stało. Jeśli chcesz, aby wiosną nadano fasolę, gdy wyraźnie użyjesz nowego, a następnie przejrzyj adnotację @Configurable. – GaryF

+0

Dzięki za wyjaśnienie! Teraz otrzymuję NoSuchBeanDefinitionException: Brak pasującej fasoli typu [org.hibernate.SessionFactory] znalezionej dla zależności: oczekiwany co najmniej 1 komponent bean, który kwalifikuje się jako kandydat na agenta dla tej zależności. Adnotacje zależności: {@ org.springframework.beans.factory.annotation.Autowired (required = true), @ org.springframework.beans.factory.annotation.Qualifier (value = sessionFactory)}. Teraz, jak widać w pliku HSR-servlet.xml, zadeklarowana została bean bean sessionFactory. Również zaktualizowałem oryginalny post z moim DAOImplem, który wygląda mi dobrze? czego mi brakuje? –

0

trzeba pobrać instancję ContactDAO z kontekstu Wiosny. Wybierasz się za pomocą słowa kluczowego new.

Zobacz poniższy link;

@Autowired annotation not able to inject bean in JUnit class

lub jeśli nie badanej jednostki

ClassPathResource resource = new ClassPathResource("beans.xml"); 
BeanFactory factory = new XmlBeanFactory(resource); 
beanFactory.getBean("nameOfYourBean"); 

http://static.springsource.org/spring/docs/2.0.x/reference/beans.html

+0

Czy mógłbyś trochę wyjaśnić, jak masz na myśli, że powinienem to zrobić? Próbowałem zastąpić ContactDAO w testrunner @Autowired ContactDAO contactDAO; ale dało mi to również wyjątek NullPointerException. –

+0

Właśnie zobaczyłem link, przeczytam to dzięki dużo. –

2

Trzeba to na szczycie swojej klasy testowej:

@RunWith(SpringJUnit4ClassRunner.class) 
// ApplicationContext will be loaded from "/applicationContext.xml" and "/applicationContext-test.xml" 
// in the root of the classpath 
@ContextConfiguration(locations={"/applicationContext.xml", "/applicationContext-test.xml"}) 
public class MyTest { 

Przypuszczałem JUnit4; moje przeoczenie.

Potrzebujesz kontekstowego znacznika konfiguracji w kontekście aplikacji gdzieś, ale nie widzę żadnego miejsca w kodzie, w którym faktycznie otwierasz plik kontekstu aplikacji i tworzony jest kontekst aplikacji. Zwykle odbywa się to za pomocą metody konfiguracji testu. Będziesz miał więcej szczęścia, jeśli faktycznie utworzysz ApplicationContext gdzieś. Spróbuj odczytać XML z CLASSPATH w metodzie instalacji i sprawdź, czy to pomaga.

+0

Przykro mi, że moja klasa wprowadzała w błąd, to nie jest tak naprawdę testklas, tylko klasa o nazwie TestRunner, którą stworzyłem, aby wypróbować funkcjonalność. Czy jednak zastosowanie @ContextConfiguration ma zastosowanie? –

+0

Nie, potrzebujesz w twoim context.xml za odpowiedź Michaela Borgwarta. – sourcedelica

+0

Zobacz mój oryginalny wpis edytowanego pliku konfiguracyjnego wiosny. Problem nadal występuje. –

1

Trzeba to w konfiguracji Wiosny w autowiring pracować

xmlns:context="http://www.springframework.org/schema/context" 
.... 
<context:annotation-config/> 
+0

Próbowałem edytować moją konfigurację wiosenną, ale problem nadal występuje. Zmieniłem mój oryginalny wpis z nową konfiguracją. –

+0

@Emil: Cóż, to spowodowało, że autowiring zawiodł mnie, ale przypuszczam, że są też inne powody. –

1

@Component/@Repository Dodaj do DAO/DAOImpl.

1

tworzysz POJO poza kontekstem sprężyny.

jeśli naprawdę chcesz, aby móc instanciate „ręcznie”, można rozwiązać ten problem, dodając <context:spring-configured /> do konfiguracji, a następnie nanoszenia ContactDAOImpl z @Configurable

Powiązane problemy