2011-01-27 9 views
8

Provare a configurare un progetto ma non riescono in Autowiring gli oggetti tramite Spring.@Outowired oggetti che ottengono il valore nullo

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; 

L'esecuzione di questo mi dà una NullPointerException quando cd.addContact viene richiamato. Il 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); 
    } 

Il mio file 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> 

Il mio file 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> 

mio file 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> 

Suppongo che l'errore sia th SessionFactory non viene inizializzato correttamente tramite @Autowired, ma perché? Potrebbe essere un semplice problema di directory/filepath o è qualcosa di più complicato?

Grazie in anticipo.

UPDATE: classe 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

possibile duplicato del [Perché è il mio campo Primavera @Autowired nullo ?] (http://stackoverflow.com/questions/19896870/why-is-my-spring-autowired-field-null) – chrylis

risposta

14

Per utilizzare le funzionalità Spring (autowiring, call to post construct metodi o aspetti) è necessario consentire a Spring di instanciare le istanze anziché utilizzare new.

Ad esempio:

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 esplorerà le classi nelle classi nel pacchetto di se.hsr.web per le classi con annotazioni Spring. Richiede Spring 3.0 per funzionare.Prima che si dovrebbe aggiungere la seguente riga nel file applicationContext.xml:

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

Grazie mille, ma questo non sta facendo uso dell'annotazione @Autowired vero? C'è un altro modo per fare questo usando l'autowiring? –

+1

@Emil - Sta usando @Autowired. Il punto è che le dipendenze sono autowired, ma che l'oggetto root (ContactDao) deve essere gestito da una molla per far sì che ciò accada. Se vuoi che i bean autowire nascano quando usi in modo esplicito new, allora guarda l'annotazione @Configurable. – GaryF

+0

Grazie per la spiegazione! Ora ottengo un NoSuchBeanDefinitionException: Nessun bean corrispondente di tipo [org.hibernate.SessionFactory] trovato per dipendenza: atteso almeno 1 bean che si qualifica come candidato autowire per questa dipendenza. Annotazioni sulle dipendenze: {@ org.springframework.beans.factory.annotation.Autowired (required = true), @ org.springframework.beans.factory.annotation.Qualifier (value = sessionFactory)}. Ora, come puoi vedere nel file servlet.xml di HSR, viene dichiarato il bean sessionFactory. Inoltre ho aggiornato il post originale con il mio DAOImpl, che mi sembra giusto? Cosa mi manca? –

0

è necessario recuperare l'istanza ContactDAO dal contesto primavera. Ti stai preparando con la parola chiave new.

Vedere il link sottostante;

@Autowired annotation not able to inject bean in JUnit class

o, se non unità di test

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

Potresti elaborare un po 'su come vuoi dire che dovrei farlo? Ho provato a sostituire ContactDAO nel testrunner con @Autowired ContactDAO contactDAO; ma mi ha dato anche una NullPointerException. –

+0

Ho appena visto il link, lo leggerò grazie mille. –

2

avete bisogno di questo in cima alla vostra classe di test:

@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 { 

ho assunto JUnit4; la mia supervisione.

È necessario il tag di configurazione del contesto in un contesto di applicazione da qualche parte, ma non vedo alcun luogo nel codice in cui si sta effettivamente aprendo un file di contesto dell'applicazione e creando un ApplicationContext. Di solito ciò avviene con un metodo di impostazione per il test. Avrai miglior fortuna se crei in qualche modo un ApplicationContext. Prova a leggere l'XML dal tuo CLASSPATH in un metodo di installazione e vedi se questo aiuta.

+0

Mi dispiace che la mia lezione sia stata fuorviante, non è proprio una classe di test, solo una classe chiamata TestRunner che ho creato per provare la funzionalità. Si applica la cosa @ContextConfiguration? –

+0

No, hai bisogno di nel tuo contesto.xml per la risposta di Michael Borgwart. – sourcedelica

+0

Vedere il mio post originale per un file di configurazione primavera modificato. Il problema persiste ancora. –

1

Hai bisogno di questo nella configurazione primavera per autowiring lavorare

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

Ho provato a modificare la mia configurazione di primavera, ma il problema persiste. Ho modificato il mio post originale con la nuova configurazione. –

+0

@Emil: beh, questo è ciò che ha causato il fallimento dell'autowiring per me, ma suppongo che ci siano anche altri motivi. –

1

Aggiungere @Component/@Repository al DAO/DAOImpl.

1

si sta creando il POJO al di fuori del contesto di primavera.

se si vuole veramente essere in grado di instanciate "manualmente", è possibile risolvere questo problema, con l'aggiunta di <context:spring-configured /> alla configurazione, e quindi annotare ContactDAOImpl con @Configurable

Problemi correlati