如何在Web应用程序中使用Spring autowire注释

时间:2012-12-18 13:50:35

标签: java spring

Spring的新手,由于我的项目需要,我已经赶紧进入了它。当我将它作为Java应用程序使用时,我成功地能够使用Spring的大多数功能,但是在Web应用程序中没有获得所需的结果。

我正在尝试在applicationContext.xml中初始化我的数据源:

<context:annotation-config />
<context:component-scan base-package="learn.spring.webapp.dao" />

<bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.postgresql.Driver" />
    <property name="url" value="jdbc:postgresql://localhost:5432/postgres" />
    <property name="username" value="postgres" />
    <property name="password" value="postgres" />
</bean>

<bean id="template" class="org.springframework.jdbc.core.JdbcTemplate"
    autowire="constructor" />

的web.xml:

 <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF/spring/applicationContext.xml</param-value>
  </context-param>

  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

我成功地能够在我的应用程序中初始化Spring,但无法在我的dao类中自动装配jdbctemplate。

package learn.spring.webapp.dao;

import learn.spring.webapp.model.Manga;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;

@Component
public class MangaDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void insert(Manga manga){
        String sql = "insert into manga_list values (?,?)";
        jdbcTemplate.update(sql,
                new Object[]{manga.getName(), manga.getAuthor()}); //Null Pointer exception
    }
}

我想在我的dao包中使用template自动装配JdbcTemplate bean。我尝试使用NullPointerException时收到JdbcTemplate。从servlet调用MangaDao。我想我可能没有正确使用自动连接的注释。请指教。

编辑:

调用DAO的servlet代码是:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        MangaDao md=new MangaDao();
        Manga manga=new Manga();
        manga.setName("Bleach");
        manga.setAuthor("Kubo Tite");
        md.insert(manga);
    }

stackTrace如下:

SEVERE: Servlet.service() for servlet TesterServlet threw exception
java.lang.NullPointerException
        at learn.spring.webapp.dao.MangaDao.insert(MangaDao.java:16)
        at learn.spring.webapp.controller.TesterServlet.doGet(TesterServlet.java:33)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:617)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
        at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:857)
        at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
        at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
        at java.lang.Thread.run(Thread.java:662)

4 个答案:

答案 0 :(得分:4)

我认为你的servlet中的代码是这样的:

Manga manga = new Manga();
manga.setName(request.getParameter("name"));
manga.setAuthor(request.getParameter("author"));
MangaDao dao = new MangaDao();
dao.insert(manga); // here you get exception;

但是,只有当你从上下文中获取bean时,自动装配才有效。

MangaDao dao = appContext.getBean(MangaDao.class);
dao.insert(manga); // should be ok;

所以你可以在哪里获得appContext。您应该从文件和商店加载它以便使用。 ContextLoaderListener为您完成此工作的一部分。然后你只需将它存储在静态变量中,例如:

@Component
public class AppContext implements ApplicationContextAware {
    private static MangaDao mangaDao = null;
    public static MangaDao getMangaDao() {
        if(mangaDao == null){
            throw new ApplicationContextException("context not initialized");
        }
        return mangaDao;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        mangaDao = applicationContext.getBean(MangaDao.class);
    }
}

确保课程AppContext包含在context:component-scan定义的包中,在您的情况下会learn.spring.webapp.dao

我强烈建议您使用交易。

答案 1 :(得分:2)

回答您的最新帖子:

您必须使用在上下文中创建的bean,而不是创建新实例。尝试自动装配新组件,然后使用它而不是在控制器中创建新组件。

@Autowired MangaDao mangaDao;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    Manga manga=new Manga();
    manga.setName("Bleach");
    manga.setAuthor("Kubo Tite");
    mangaDao.insert(manga);
}

回答原帖:

看起来您在组件扫描中缺少正确的包名称。您的@Component带注释的类位于learn.spring.webapp.model包中,并且您的扫描未到达它。尝试在注释扫描中使用更通用的包:

<context:component-scan base-package="learn.spring.webapp" />

答案 2 :(得分:0)

我建议使用spring-mvc而不是原始Servlet。

使用spring-mvc定义控制器而不是Servlet。根据您的代码,Spring Controller可能看起来像这样:

@Controller 
public class MangaController {

    @Autowired
    private MangaDao dao;

    @RequestMapping(value = "/manga/insert", method = RequestMethod.GET)
    public void doGet() {
        Manga manga = new Manga();
        manga.setName("Bleach");
        manga.setAuthor("Kubo Tite");
        dao.insert(manga);
    }
}

由于Controller由Spring管理,所有必需的依赖项都将被注入并准备好供您的代码使用 - 消除了NullPointerException

applicationContext.xml内,您必须在组件扫描中包含控制器包,并启用mvc功能:

<mvc:annotation-driven />

我强烈建议您在spring-mvc入门时阅读this article。它涵盖了所有必需的步骤以及您需要的Spring依赖项。

我还建议您浏览Spring Reference documentation,正如您所看到的,它非常全面!

答案 3 :(得分:0)

在使用“ SpringBeanAutowiringSupport”抽象类之前,我有同样的“空”异常。 您应该使用以下抽象类扩展该类:

public class SomeClass extends SpringBeanAutowiringSupport {}