为什么我的Spring @Autowired字段返回null?

时间:2016-06-26 12:56:10

标签: java spring spring-mvc

这不是this问题的重复。所以请不要因为“重复”原因而关闭它。

我正在尝试将bean自动装入java类。我的问题是playerDAO保持为空并且没有初始化。

MVC-调度-service.xml中

<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"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <context:component-scan base-package="ngdemo"/>

    <mvc:annotation-driven/>

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <tx:annotation-driven transaction-manager="transactionManager"/>    
</beans>

PlayerDAO.java

@Repository
@SuppressWarnings({"unchecked", "rawtypes"})
public class PlayerDAO {
    @Autowired
    private SessionFactory sessionFactory;

    @Transactional
    public Player getPlayerByUsername(String username) {
      //some code
    }
}

LoginRestService.java

@Path("/v1")
@Controller
public class LoginRestService {

    @Autowired
    private PlayerDAO playerDAO;

    @Path("/login")
    @POST
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public Response authenticateUser(@FormParam("username") String username,
                                     @FormParam("password") String password, @Context UriInfo request) {
     playerDAO.getPlayerByUsername(username);
     //NPE, playerDAO here is null when I'm trying to access it
    }    
}

我错过了什么?

此处提供完整代码:https://github.com/Ferenus/hestalis

5 个答案:

答案 0 :(得分:1)

您确定您的控制器包名称是&#34; ngdemo&#34;不是&#34; com.pack.ngdemo&#34; ?你在使用数据库吗?可能是你从查询中获得空值你可以告诉我你在getplayerbyusername()方法中使用了什么查询。

  

试试这个

public TypedQuery<User> findUsersByNameEquals(String name) {
    if (name == null || name.length() == 0) { 
        throw new IllegalArgumentException("The name argument is required"); 
    }

    TypedQuery<User> q = entityManager.createQuery("SELECT o FROM User AS o WHERE o.username = :name", User.class);
    q.setParameter("name", name);

    return q;
}
  

public boolean loginWithUserPass(String username, String password){

    TypedQuery<User> q = entityManager.createQuery("SELECT o FROM User AS o WHERE o.username = :name and o.password = :pass", User.class);
    q.setParameter("name", username);
    q.setParameter("pass", password);

    List<User> results = q.getResultList();
    if (!results.isEmpty()) return true;

    else return false;
}

不要尝试完全相同的代码,因为我使用过实体管理器。尝试类似的东西。可能这会有所帮助。

答案 1 :(得分:1)

我已经检查了你的代码,我得到了你的问题的答案。

您的代码没有任何问题。

但是当你想要使用spring mvc和jersey restfull webservices时,你必须做的事情比你在这里做的更多。 Bcoz球衣并不了解弹簧容器及其实施情况。因此,无论何时您要求使用webservice jersey,都要填写您的请求处理而不是弹簧框架。

所以,这里的playerDao没有注入LoginRestService.java,因此它(playerDao)解析为null。

执行以下步骤,

步骤1: - 将以下maven依赖项添加到您的pom.xml

    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
       <artifactId>jersey-spring</artifactId>
        <version>1.19.1</version>
   <dependency>

此依赖项用于集成Spring和Jersey

步骤2 : - 现在创建一个WebApplicationContext,以读取 mvc-dispatcher-servlet.xml 中的所有配置信息。对于此副本,将以下代码添加到web.xml

<context-param>
   <param-name>contextConfigLocation</param-name>
   <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
</context-param>
<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

步骤3: - 现在使用提供的类 com.sun.jersey.spi.spring.container.servlet.SpringServlet 的泽西框架整合spring和jersey(该课程可在jersey-spring.jar中找到。对于此副本,以下代码到您的web.xml

<servlet>
        <servlet-name>jersey-serlvet</servlet-name>

        <servlet-class>
            com.sun.jersey.spi.spring.container.servlet.SpringServlet
        </servlet-class>

        <init-param>
            <param-name>com.sun.jersey.config.property.packages</param-name>
            <param-value>ngdemo.rest</param-value>
        </init-param>

        <init-param>
            <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
            <param-value>true</param-value>
        </init-param>

        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/rest/*</url-pattern>
    </servlet-mapping>

多数民众赞成。一切都完成了。

只需更新您的maven项目并再次在服务器中运行。

<强>建议  当您添加依赖项(jersey-spring-1.19.1.jar)时,还有一些与弹簧相关的jar文件(如spring-aop.3.0.0CR.jar,spring-bean.jar等等)包含在您的maven中依赖项和包含的jar是旧版本。所以有时你可能会得到 ClassNotFoundException 。所以你必须排除那些spring依赖项。 如果你得到这种Exception,请将以下代码复制到你的jersey-spring.jar的 元素

<dependency>
    <groupId>com.sun.jersey.contribs</groupId>
    <artifactId>jersey-spring</artifactId>
    <version>1.19.1</version>
    <exclusions>
        <exclusion>
            <artifactId>spring-context</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>spring-core</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>spring-beans</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>spring-web</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
        <exclusion>
            <artifactId>spring-aop</artifactId>
            <groupId>org.springframework</groupId>
        </exclusion>
    </exclusions>
</dependency>

我希望这会对你有所帮助。让我知道你是否得到了正确的解决方案。

答案 2 :(得分:0)

我建议你使用接口代替实现,在你的控制器中注入DAO实现,同时你应该注入服务接口。

如果您不想使用服务类,我建议您注入一个接口:

public class PlayerDAO implements IPlayerDAO

并在你的控制器中注入接口。

public class LoginRestService {

    @Autowired
    private IPlayerDAO IPlayer;

这是一个很好的做法。

另一方面,您在DAOS中设置事务,这不是一个好主意,您应该在服务类中指定它。

最后谈论你的问题,在spring组件中为null,通常是因为没有正确指定组件扫描。

问候。

答案 3 :(得分:0)

我尝试了你的应用程序的github版本,添加了一个测试,它工作正常:https://github.com/michalmela/hestalis

检查您的测试配置。另外,请不要按照其他响应的建议,无缘无故地添加服务接口。

答案 4 :(得分:0)

尝试在PlayerDAO类的顶部提供@Component注释。可能就是这样你的bean将被Spring正确扫描。这将在Spring Container中注册bean。如果有帮助,请告诉我:)。