簡體   English   中英

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

[英]Why is my Spring @Autowired field returns null?

這不是這個問題的重復。 因此,請不要因為“重復”原因而關閉它。


我正在嘗試將bean自動裝配到java類中。 我的問題是playerDAO仍然為null,並且沒有初始化。

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

您確定Controller軟件包名稱是“ ngdemo”而不是“ com.pack.ngdemo”嗎? 您是否在使用數據庫? 可能是您從查詢中獲取了空值,請告訴我您在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;
}

不要嘗試完全相同的代碼,因為我使用過實體管理器。 嘗試類似的東西。 也許這會有所幫助。

我檢查了您的代碼,並得到了您的問題的答案。

您的代碼沒有錯。

但是,當您想同時使用spring mvc和jersey restfull Web服務時,除了要做的以外,您還需要做更多的事情。 Bcoz球衣不知道spring container及其實現。 因此,每當您請求Web Service jersey時,將完全處理您的請求,而不是spring框架。

因此,此處的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的 jersey框架集成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依賴項。 如果您收到此類異常,請將以下代碼復制到 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>

我希望這可以幫助你。 讓我知道您是否找到正確的解決方案。

我建議您使用接口代替實現,在控制器中注入DAO實現,而注入服務接口。

如果您不想使用服務類,我建議您注入一個接口:

public class PlayerDAO implements IPlayerDAO

並在您的控制器注入界面中。

public class LoginRestService {

    @Autowired
    private IPlayerDAO IPlayer;

這是一個好習慣。

另一方面,您要在DAOS中設置事務性,這不是一個好主意,您應該在服務類中指定它。

最后說說您的問題,通常在spring組件中為null,這是因為未正確指定組件掃描。

問候。

我嘗試了您應用程序的github版本,添加了一個測試,它運行良好: https : //github.com/michalmela/hestalis

檢查您的測試配置。 另外,請不要無緣無故地遵循其​​他響應的建議添加服務接口。

嘗試在PlayerDAO類的頂部添加@Component批注。 可能是這樣,Spring會正確掃描您的bean。這將確保在Spring Container中注冊該bean。 讓我知道是否有幫助:)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM