spring boot autoconfiguration with jdbc template autowiring dataSource issue

时间:2014-12-29 22:51:32

标签: spring jdbc datasource spring-boot autowired

我是Spring和J2EE的新手。我在使用带有Spring Boot自动配置的JDBC模板时遇到了麻烦。

我所做的就是提供了here提供的RESTful Web服务示例 并决定将其扩展为使用JDBC模板关系数据库访问。不幸的是,提供的另一个example没有用,因为不考虑从xml beans文件提供dataSource的唯一困难。

我试图解决这个问题:

  1. 使用DAO Impl类作为Spring的不同实现的扩展。
  2. 添加到bean文件。
  3. 使用不同的DataSource类(例如DriverManagerDataSource)。
  4. 尝试在不同的类中自动装配一个简单的属性(比数据源更复杂的东西)。
  5. 在开始时,我刚刚编写了DAO类,但是后来我可能只有在实现了接口的情况下才可以自动装配数据源,试过它,没有帮助。
  6. 我尝试了在Stack或Google上找到的所有内容。大多数示例都严重过时或未得到答复,或与Spring Boot Autoconfiguration等无关。

    我不断遇到Property 'dataSource' is required错误,如果最终设法将application-config.xml文件与bean链接,但无法设法为JDBC的数据源自动装配。

    我绝望地完成它并严重阻止,出于想法,如果有人可以提供一个最新的示例,使用Spring Boot Autoconfigurations,XML中的bean查找,JDBC的自动数据源,我会很高兴。

    或者至少有一些想法,线索,甚至是如何寻找它,因为我甚至没有谷歌的关键词。

    谢谢!

    enter image description here

    Spring Application类。

    package ws;
    
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.SpringApplication;
    import org.springframework.context.annotation.ComponentScan;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.ImportResource;
    
    @Configuration
    @ComponentScan
    @ImportResource("classpath:spring/application-config.xml")
    @EnableAutoConfiguration
    public class Application {
    
        public static void main(String[] args) {
            SpringApplication.run(Application.class, args);
        }
    }
    

    Web服务类。

    package ws;
    
    import dao.UserDAOImpl;
    import model.User;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestWS {
        @RequestMapping("/greeting")
        public User greeting(@RequestParam(value="name", defaultValue="World") String name) {
        return new User("ubububu", "661331555", 0);
        }
        @RequestMapping("/create")
        public String initialize() {
            UserDAOImpl users = new UserDAOImpl();
            users.init();
            return "seems ok";
        }
    }
    

    DAO接口

    package dao;
    
    import model.User;
    
    public interface UserDAO {
        public void insert(User usr);
        public void init();
        public User select(int id);
    }
    

    DAO实施

    package dao;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.datasource.DriverManagerDataSource;
    import org.springframework.stereotype.Repository;
    
    import model.User;
    import dao.UserDAO;
    
    @Repository
    public class UserDAOImpl implements UserDAO {
        private JdbcTemplate jdbcTemplate;
        private DriverManagerDataSource dataSource;
        @Autowired
        public void setDataSource(DriverManagerDataSource dataSource) {
            this.dataSource = dataSource;
        }
    
        public void insert(User usr) {
            String sql = "INSERT INTO USER " +
                    "(USR_ID, EMAIL, PHONE) VALUES (?, ?, ?)";
    
            this.jdbcTemplate = new JdbcTemplate(dataSource);
            jdbcTemplate.execute(sql);
        }
    
        public void init() {
            String sql = "CREATE TABLE USER (USR_ID INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,EMAIL VARCHAR(30) NOT NULL,PHONE VARCHAR(15) NOT NULL)";
            this.jdbcTemplate = new JdbcTemplate(dataSource);
            jdbcTemplate.execute(sql);
        }
    }
    

    数据模型

    package model;
    
    public class User {
        private String email;
        private String phone;
        private int id;
        public User(String email, String phone, int id) {
            this.email = email;
            this.phone = phone;
            this.id = id;
        }
        public int getUsrId(){
            return this.id;
        }
        public String getUsrEmail() {
            return this.email;
        }
        public String getUsrPhone() {
            return this.phone;
        }
    }
    

    配置bean文件

    <?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.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        <import resource="Spring-User.xml" />-->
        <context:component-scan base-package="ws"/>
        <bean id="ds" 
             class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    
            <property name="driverClassName" value="org.springframework.jdbc.core.JdbcTemplate" />
            <property name="url" value="jdbc:mysql://localhost/:3306/databasename" />
            <property name="username" value="root" />
            <property name="password" value="password" />
        </bean>
        <bean id="UserDAOprovider" class="dao.UserDAOImpl">
            <property name="dataSource" ref="ds" />
        </bean> 
    
    </beans>
    

    错误消息:

    ERROR [dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required] with root cause
    java.lang.IllegalArgumentException: Property 'dataSource' is required
        at org.springframework.jdbc.support.JdbcAccessor.afterPropertiesSet(JdbcAccessor.java:135) ~[spring-jdbc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.jdbc.core.JdbcTemplate.<init>(JdbcTemplate.java:169) ~[spring-jdbc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at dao.UserDAOImpl.init(UserDAOImpl.java:66) ~[demo3-0.0.1-SNAPSHOT.jar!/:na]
        at ws.TestWS.initialize(TestWS.java:30) ~[demo3-0.0.1-SNAPSHOT.jar!/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.6.0_33]
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.6.0_33]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.6.0_33]
        at java.lang.reflect.Method.invoke(Method.java:622) ~[na:1.6.0_33]
        at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:749) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:689) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:938) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:870) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:852) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:620) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837) ~[spring-webmvc-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:727) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.0.8.RELEASE.jar!/:4.0.8.RELEASE]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:503) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1070) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1695) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1146) ~[na:1.6.0_33]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) ~[na:1.6.0_33]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-7.0.57.jar!/:7.0.57]
        at java.lang.Thread.run(Thread.java:701) ~[na:1.6.0_33]
    

1 个答案:

答案 0 :(得分:30)

在Spring Boot中配置DataSource的最简单方法是在src / main / resources下创建一个application.properties文件,其中包含以下内容(可能需要使用正确的URL,用户名和密码进行更新):

spring.datasource.url=jdbc:mysql://localhost/:3306/databasename
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Spring Boot会自动为您创建DataSource类并将其注入其他bean。因此,您将不再需要xml配置文件,并且可能会在Application类中删除此行:

@ImportResource("classpath:spring/application-config.xml")

此外,在UserDAOImpl中,Spring可以使用DataSource bean(http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html#boot-features-using-jdbc-template)自动装配JdbcTemplate对象,因此每次调用insert()方法时都不需要创建一个。

对于UserDAOImpl中的init()方法,您可以在src / main / resources下创建一个schema.sql文件,并在那里移动CREATE TABLE语句(有关详细信息,请参阅http://docs.spring.io/spring-boot/docs/1.2.0.RELEASE/reference/htmlsingle/#howto-intialize-a-database-using-spring-jdbc

有关详细信息,请参阅此示例:http://xantorohara.blogspot.ca/2013/11/spring-boot-jdbc-sample.html