Spring Web App - Простой шаблон JDBC Советы? - PullRequest
1 голос
/ 13 января 2011

Быстрый вопрос на основе весеннего веб-приложения, которое я создаю.

Как вы настраиваете контекст приложения так, что вам не нужно постоянно задавать параметры источника данных для simpleJDBC, и вы можете вызвать getSimpleJDBCTemplate (). Queryfor ....с источником данных.

Вот так у меня сейчас и кажется, что это противоречит инверсии управления, которую должна обеспечивать пружина, как это происходит в каждом дао!

 ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml");
    DataSource dataSource = (DataSource) ac.getBean("dataSource");
    SimpleJdbcTemplate simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);

ApplicationContext

<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-2.5.xsd
   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
<property name="location" value="classpath:properties.properties"/>
</bean>

    <bean id="dataSource" destroy-method="close" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
    </bean>

 <bean name="SimpleJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
    <constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>


      <context:annotation-config/>
   </beans>

Последняя трассировка стека из журнала Tomcat

13-Jan-2011 20:15:18 com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
  ptc.jersey.spring
13-Jan-2011 20:15:18 com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
  class ptc.jersey.spring.resources.LoginResource
13-Jan-2011 20:15:18 com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
13-Jan-2011 20:15:19 com.sun.jersey.spi.spring.container.servlet.SpringServlet getContext
INFO: Using default applicationContext
13-Jan-2011 20:15:19 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.4 09/11/2010 10:30 PM'
13-Jan-2011 20:15:21 com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
    at ptc.jersey.spring.daoImpl.UserDaoImpl.getUser(UserDaoImpl.java:43)

web.xml

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

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:ApplicationContext.xml</param-value>
</context-param>


    <servlet>
        <servlet-name>Jersey Spring Web Application</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>ptc.jersey.spring</param-value>
</init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>Jersey Spring Web Application</servlet-name>
        <url-pattern>/resources/*</url-pattern>
    </servlet-mapping>
</web-app>

Любая помощь будетбольшое спасибо Крис

Ответы [ 4 ]

5 голосов
/ 13 января 2011

Почему бы вам не объявить экземпляр SimpleJdbcTemplate также в файле контекста приложения?

Например, с этими объявлениями bean-компонентов

<bean name="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.gjt.mm.mysql.Driver"/>
    <property name="url" value="dburl"/>
    <property name="username" value="dbusername"/>
    <property name="password" value="password"/>
</bean>

<bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
    <constructor-arg><ref bean="dataSource"/></constructor-arg>
</bean>

И в вашем файле web.xml загрузитьконтекст приложения

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

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:ApplicationContext.xml</param-value>
</context-param>
2 голосов
/ 13 января 2011

Объявите bean-компонент SimpleJdbcTemplate в контексте:

<bean name="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
    <constructor-arg ref="dataSource"/>
</bean>

и используйте его так:

ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:ApplicationContext.xml");
SimpleJdbcTemplate simpleJdbcTemplate = (SimpleJdbcTemplate) ac.getBean("jdbcTemplate");

или в DAO:

@Autowired
private SimpleJdbcTemplate simpleJdbcTemplate;

Это поточно-ориентированный и, следовательно, многоразовый.

0 голосов
/ 27 января 2011

Если вы создаете SimpleJdbcTemplate внутри setDataSource, то вы создаете шаблон для экземпляра Dao. Если вы сконфигурируете как bean-компонент и внедрите его в Dao, вы сможете повторно использовать один и тот же шаблон через Daos, что рекомендуется, поскольку он безопасен для потоков.

0 голосов
/ 13 января 2011

Я бы порекомендовал вам объявить ваш DataSource как bean-компонент и также классы, которые в этом нуждаются, и использовать внедрение зависимостей, чтобы ввести DataSource в ваш класс.Например, определение вашего компонента может выглядеть следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans">    
  <bean id="dataSource" class="...">
    <!-- your dataSource config here -->
  </bean>    
  <bean id="yourClassThatNeedsDataSource" class="com.stackoverflow.q4684102.Example">
    <property name="dataSource" ref="dataSource" />
  </bean>    
</beans>

и сопровождающий его класс

package com.stackoverflow.q4684102;
import javax.jdbc.DataSource;
import org.springframework.jdbc.core.simple.*;

public class Example implements YourDaoInterface {    
    private SimpleJdbcOperations jdbc;

    public void setDataSource(DataSource ds) {
        jdbc = new SimpleJdbcTemplate(ds);
    }    
    // your DAO methods here
}

Почему это делается вместо создания компонента изSimpleJdbcTemplate сам по себе?

На самом деле без разницы - некоторым это нравится по-другому, другим это нравится - у вас не будет огромного XML с множеством определений бинов для промежуточных объектов, еслиделай так, это точно.Это, конечно, решать вам, как вы хотите разработать свое программное обеспечение.

...