Jersey + Spring 3 + Maven 3 + Tomcat 7 @Component Class中的@Resource始终为null

Den*_*nis 5 eclipse spring tomcat jersey maven

我已经搜索并尝试了我能想到的所有解决方法,但TestService类中的Dao始终为null.我看到Spring日志显示Dao被注入以及TestService类.我试过在WTP下运行eclipse以及在Tomcat中直接运行.两者都会导致相同的错误.任何人都可以帮助解密错误导致Dao在TestService类中为空的位置.

版本:

Jersey 1.8
Spring 3.0.5Release
Tomcat apache-tomcat-7.0.27 
Maven  3.0.3 (r1075438; 2011-02-28 12:31:09-0500)
Java 1.6.0_31

Eclipse Java EE IDE for Web Developers. 
Version: Indigo Service Release 2
Build id: 20120216-1857 
Run Code Online (Sandbox Code Playgroud)

记录 - 显示正在进行的注射(为简洁起见,切断DEBUG和ClassNames)

 Creating shared instance of singleton bean 'dataSource' 
 Creating instance of bean 'dataSource' 
 Eagerly caching bean 'dataSource' to allow for resolving potential circular references 
 Finished creating instance of bean 'dataSource' 
 Creating shared instance of singleton bean 'jdbcTemplate' 
 Creating instance of bean 'jdbcTemplate' 
 Eagerly caching bean 'jdbcTemplate' to allow for resolving potential circular references 
 Returning cached instance of singleton bean 'dataSource' 
 Invoking afterPropertiesSet() on bean with name 'jdbcTemplate' 
 Finished creating instance of bean 'jdbcTemplate' 
 Creating shared instance of singleton bean 'testClassDao' 
 Creating instance of bean 'testClassDao' 
Found injected element on class [test.dao.TestClassDao]: AutowiredMethodElement for public void test.dao.TestClassDao.setDataSource(javax.sql.DataSource) 
 Eagerly caching bean 'testClassDao' to allow for resolving potential circular references 
Processing injected method of bean 'testClassDao': AutowiredMethodElement for public void test.dao.TestClassDao.setDataSource(javax.sql.DataSource) 
 Returning cached instance of singleton bean 'dataSource' 
 Autowiring by type from bean name 'testClassDao' to bean named 'dataSource' 
 Finished creating instance of bean 'testClassDao' 
 Creating shared instance of singleton bean 'testService' 
 Creating instance of bean 'testService' 
Found injected element on class [test.service.admin.TestService]: AutowiredFieldElement for test.dao.TestClassDao test.service.admin.TestService.dao 
 Eagerly caching bean 'testService' to allow for resolving potential circular references 
Processing injected method of bean 'testService': AutowiredFieldElement for test.dao.TestClassDao test.service.admin.TestService.dao 
 Returning cached instance of singleton bean 'testClassDao' 
Autowiring by type from bean name 'testService' to bean named 'testClassDao' 
 Finished creating instance of bean 'testService' 
Run Code Online (Sandbox Code Playgroud)

错误 - TestService.java中的空指针异常,因为TestClassDao为null

Apr 25, 2012 9:07:04 PM org.apache.catalina.core.StandardWrapperValve invoke
SEVERE: Servlet.service() for servlet [jersey] in context with path [/test-service]     threw exception
java.lang.NullPointerException
at test.service.admin.TestService.createCompanyProfile(TestService.java:35)
Run Code Online (Sandbox Code Playgroud)

TestClassDao.java

package test.dao;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;

import test.domain.TestClass;

@Repository
public class TestClassDao {

    private NamedParameterJdbcTemplate namedParamJdbcTemplate;
    private DataSource dataSource;


    @Autowired 
    public void setDataSource(DataSource dataSource) {
        this.dataSource = dataSource;
        this.namedParamJdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
    }

    public void insertTestClass(TestClass testClass)
    {       
        String query = "INSERT INTO TEST_CLASS_TABLE(NAME) VALUES (:NAME)";

        MapSqlParameterSource namedParams = new MapSqlParameterSource();

        mapParams(namedParams, testClass);

        namedParamJdbcTemplate.update(query, namedParams);
    }




    private void mapParams(MapSqlParameterSource  namedParams, TestClass testClass)
    {

            namedParams.addValue("NAME", testClass.getName());

    }
}
Run Code Online (Sandbox Code Playgroud)

TestClass.java

 package test.domain;
 import java.util.Date;
 import java.util.HashSet;
 import java.util.Set;

public class TestClass  implements java.io.Serializable {
    private String name;

    public TestClass(String name){
        this.name = name;

    }

    public String getName() {
        return this.name;
    }
}
Run Code Online (Sandbox Code Playgroud)

TestService.java

package test.service.admin;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import test.dao.TestClassDao;
import test.domain.TestClass;

@Path("/resttest")
@Component
public class TestService {
    @Context
    UriInfo uriInfo;
    @Context
    Request request;
    @Autowired 
    TestClassDao dao;

    static Logger log = Logger.getLogger(TestService.class);

    @GET
    @Path("/test")
    public String createCompanyProfile() {

        TestClass test = new TestClass("MyTestName");

        dao.insertTestClass(test);

        return "test done";
    }
}
Run Code Online (Sandbox Code Playgroud)

applicationContext.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: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:annotation-config />

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql://localhost:1234/testClassDatabase" />
        <property name="username" value="user" />
        <property name="password" value="password" />
    </bean>

    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource">
            <ref bean="dataSource" />
        </property>
    </bean>
    <context:component-scan base-package="test"/>
</beans>
Run Code Online (Sandbox Code Playgroud)

web.xml中

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>jersey</servlet-name>
        <servlet-class>
            com.sun.jersey.spi.container.servlet.ServletContainer
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>jersey</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>  
</web-app>
Run Code Online (Sandbox Code Playgroud)

更新:为web-app添加了这个,但它没有改变任何东西

<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
Run Code Online (Sandbox Code Playgroud)

pom.xml - 我认为这可能是问题所在,依赖或其他什么

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>test-service</groupId>
    <artifactId>test-service</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Test Service</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <!-- Jersey -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.19</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>com.sun.jersey</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <!-- Spring 3 dependencies -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>

        <!-- Jersey + Spring -->
        <dependency>
            <groupId>com.sun.jersey.contribs</groupId>
            <artifactId>jersey-spring</artifactId>
            <version>${jersey.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-web</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-beans</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.springframework</groupId>
                    <artifactId>spring-context</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.8.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>test-service</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.6</source>
                    <target>1.6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
    <properties>
        <org.springframework.version>3.0.5.RELEASE</org.springframework.version>
        <jersey.version>1.8</jersey.version>
    </properties>
</project>
Run Code Online (Sandbox Code Playgroud)

更新修复:我的朋友看了一下,注意到我没有为com.sun.jersey.config.property.packages设置参数,一旦我们添加了,所有内容都自动生效.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:server-context.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    </listener>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <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>service</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>  
</web-app>
Run Code Online (Sandbox Code Playgroud)

Rya*_*art 7

春天注入 TestService的实例有一个DAO,但是该实例不是请求要去一个.你正在使用Jersey的ServletContainer来托管你的Jersey应用程序,它不会以任何方式与Spring集成.它将根据需要自行创建实例,显然不会被Spring注入(无论如何都不做一些字节码编织).我建议使用SpringServlet,它是一个ServletContainer,它知道如何从Spring上下文中获取资源类.这将清除你的问题.