@Autowired объекты получают нулевое значение - PullRequest
8 голосов
/ 27 января 2011

Попытка настроить проект, но не удалось выполнить автоматическое связывание объектов через Spring.

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;

При выполнении этого возникает исключение NullPointerException при вызове cd.addContact.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);
    }

Мой файл сервлета:

    <?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>

Мой файл 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>

Мой файл 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>

Полагаю, ошибка в том, что SessionFactory не инициализируется правильно через @Autowired, но почему?Может ли это быть простая структура каталогов / проблема с файловым путем или что-то более сложное?

Заранее спасибо.

ОБНОВЛЕНИЕ: Класс ContactDAOImpl:

@Repository
public class ContactDAOImpl extends HibernateDaoSupport implements ContactDAO{

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

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

Ответы [ 6 ]

14 голосов
/ 27 января 2011

Чтобы использовать функции Spring (автоматическое подключение, вызов методов или аспектов построения), вам нужно разрешить Spring создавать экземпляры вместо использования new.

Например:

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 будет сканировать классы в классах в пакете se.hsr.web для поиска классов с аннотациями Spring. Для работы требуется Spring 3.0. Перед этим вы должны добавить в ваш файл applicationContext.xml следующую строку:

<context:component-scan base-package="se.hsr.web" />
2 голосов
/ 27 января 2011

Вам нужно это наверху вашего тестового класса:

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

Я предположил JUnit4; мой недосмотр.

Вам нужен где-то тег конфигурации контекста в контексте приложения, но я не вижу в вашем коде места, где вы фактически открываете файл контекста приложения и создаете ApplicationContext. Обычно это делается в методе настройки для вашего теста. Вам повезет больше, если вы где-нибудь создадите ApplicationContext. Попробуйте прочитать XML из CLASSPATH в методе установки и посмотрите, поможет ли это.

1 голос
/ 05 июня 2012

вы создаете POJO вне контекста пружины.

Если вы действительно хотите иметь возможность создавать «вручную», вы можете это исправить, добавив <context:spring-configured /> в свою конфигурацию, а затем добавив аннотацииContactDAOImpl с @Configurable

1 голос
/ 07 ноября 2011

Добавьте @Component/@Repository к DAO / DAOImpl.

1 голос
/ 27 января 2011

Это необходимо в конфигурации Spring для автоматического подключения

xmlns:context="http://www.springframework.org/schema/context" 
....
<context:annotation-config/>
0 голосов
/ 27 января 2011

Вам необходимо получить экземпляр ContactDAO из контекста Spring. Вы начинаете себя с ключевого слова new.

См. Ссылку ниже;

@ Аннотация с автоматической проводкой не может вводить компонент в классе JUnit

или, если не модульный тест

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

...