简体   繁体   English

Spring @Autowired实例为null

[英]Spring @Autowired instance is null

I'm currently trying to setup a REST Service Spring application and have implemented a model and its controller + the dao and service to talk to a MySQL database. 我目前正在尝试设置REST Service Spring应用程序,并实现了一个模型及其控制器+ dao和服务以与MySQL数据库进行通信。

在此处输入图片说明

Now my AccountController is a bean with annotated @RestController, while AccountService is a @Component bean. 现在,我的AccountController是带有注释的@RestController的bean,而AccountService是@Component Bean。 The AccountService holds an @Autowire'd AccountDao member and AccountController holds an @Autowire'd AccountService member. AccountService拥有一个@ Autowire'd AccountDao成员,而AccountController拥有一个@ Autowire'd AccountService成员。

The dataAccess.xml is as follows: dataAccess.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"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
      destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:3306/fashion" />
        <property name="username" value="root" />
        <property name="password" value="fashion" />
    </bean>

    <bean id="sessionFactory"
      class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="mappingResources">
            <list>
                <value>de/appsiting/fashion/model/Account.hbm.xml</value>
           </list>
        </property>
        <property name="hibernateProperties">
           <props>
                <prop key="hibernate.dialect">
                org.hibernate.dialect.MySQL5Dialect
                </prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
           </props>
        </property>
    </bean>

    <bean id="jdbcExceptionTranslator" class="org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator">
       <property name="dataSource">
            <ref bean="dataSource" />
       </property>
    </bean>

    <bean id="accountDao" class="de.appsiting.fashion.persistence.AccountDao" />
</beans>

However the Account.hbm.xml is colored in red indicating it isn't found by the application. 但是, Account.hbm.xml被涂成红色,表明应用程序找不到它。 Thus my first question, why doesn't it root from resources folder to find the .hbm.xml 因此,我的第一个问题是,为什么不从resources文件夹中根目录找到.hbm.xml?

The serviceBeans.xml is filled as follows: 如下所示填充serviceBeans.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:task="http://www.springframework.org/schema/task"
       xsi:schemaLocation="
    http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <task:annotation-driven/>

    <bean id="hibernateStringEncryptor" class="org.jasypt.hibernate4.encryptor.HibernatePBEStringEncryptor">
        <property name="registeredName">
            <value>strongHibernateStringEncryptor</value>
        </property>
        <property name="algorithm">
            <value>PBEWithMD5AndTripleDES</value>
        </property>
        <property name="password">
            <value>jasypt</value>
        </property>
    </bean>

    <bean id="accountService" class="de.appsiting.fashion.service.AccountService">
        <property name="accountDao" ref="accountDao" />
    </bean>

    <!-- *** TX LAYER -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <tx:advice id="tx.advice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="*" propagation="REQUIRED" read-only="false" />
            <tx:method name="get*" propagation="REQUIRED" read-only="false" />
        </tx:attributes>
    </tx:advice>

    <!-- *** AOP -->
    <aop:config>
        <aop:pointcut id="accountServiceMethods" expression="execution(* de.appsiting.fashion.service.AccountService.*(..))" />

        <aop:advisor advice-ref="tx.advice" pointcut-ref="accountServiceMethods" />
    </aop:config>
</beans>

Now when running my AccountTest the accountService is null and thus the Test fails: 现在,当运行我的AccountTest时 ,accountService为null,因此测试失败:

import de.appsiting.fashion.service.AccountService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.junit.Test;


/**
 * Created by mak on 4/22/16.
 */
public class AccountTest {
    private static Logger log = Logger.getLogger(AccountTest.class);

    @Autowired
    private AccountService accountService;

    @Test
    public void testCreateAccount() throws Exception {
        Account account = new Account();
        account.setUsername("testfashion");
        account.setPassword("testfashion");
        account.setEmail("test@appsiting");

        accountService.addAccount(account);
    }
}

Why does this happen? 为什么会这样?

You should use SpringJUnit4ClassRunner in order to initialize the application context, so the dependency injection is able to run. 您应该使用SpringJUnit4ClassRunner来初始化应用程序上下文,以便依赖项注入能够运行。

Another option is to use Mockito , which in IMHO avoids lots of troubles and you get the benefits of using mocks. 另一个选择是使用Mockito ,它在恕我直言中避免了很多麻烦,并且您获得了使用模拟的好处。

You are missing two configurations on your tests. 您在测试中缺少两种配置。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"Location of xml files that you need to load for tests to run"})
public class AccountTest {

}

Above configuration will load the context for your tests. 以上配置将为您的测试加载上下文。 Or you can load the application context for your tests in the setup method and then use that context you get your account service. 或者,您可以在设置方法中加载测试的应用程序上下文,然后使用该上下文获取帐户服务。

I think you should add the following in your serviceBeans.xml, 我认为您应该在serviceBeans.xml中添加以下内容,

<bean id="accountDao" class="de.appsiting.fashion.persistence.AccountDao" />

and delete the @Autowired AccountDao annotation in the AccountService class and add a setter of AccountDao . 并删除AccountService类中的@Autowired AccountDao批注,并添加一个AccountDao的设置器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM