创建名称为 'dataSource' 的 bean 在 com.vinay.patients.config.AppConfig 中定义时出错:不满意

Error creating bean with name 'dataSource' defined in com.vinay.patients.config.AppConfig: Unsatisfied

我是 Spring 4 框架的新手,试图从嵌入式 HyperSQL 获取字符串 eclipse sfs 中的数据库,但收到此错误,错误创建名称为 'dataSource' 的 bean 在 com.vinay.patients.config.AppConfig 中定义。

错误日志:

javax.servlet.ServletException: Servlet.init() for servlet dispatcher threw exception
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)
root cause

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource' defined in com.vinay.patients.config.AppConfig: Unsatisfied dependency expressed through method 'dataSource' parameter 0: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
    org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source)
root cause

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [java.lang.String] found for dependency [java.lang.String]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1398)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1051)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1018)
    org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:834)
    org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
    org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:467)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1123)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1018)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
    org.springframework.beans.factory.support.AbstractBeanFactory.getObject(AbstractBeanFactory.java:306)
    org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
    org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
    org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
    org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
    org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
    org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
    org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668)
    org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540)
    org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494)
    org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
    javax.servlet.GenericServlet.init(GenericServlet.java:160)
    org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
    org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1041)
    org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:603)
    org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
    java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    java.lang.Thread.run(Unknown Source) 

AppConfig.java

package com.vinay.patients.config;

import org.apache.tomcat.dbcp.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

import java.sql.SQLException;

import javax.sql.DataSource;

@Configuration
@EnableWebMvc
@Component
@ComponentScan(basePackages = "com.vinay.patients")
public class AppConfig extends WebMvcConfigurerAdapter {

    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

    // @Bean
    // public DataSource getDataSource() {
    // DriverManagerDataSource dataSource = new DriverManagerDataSource();
    // dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    // dataSource.setUrl("jdbc:mysql://localhost:8080/healthcare");
    // dataSource.setUsername("root");
    // dataSource.setPassword("root");
    // return dataSource;
    // }
    @Bean
    public DataSource dataSource(String string, String string2, String string3, String string4) throws SQLException {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName("org.h2.Driver"); // you can call your code here
        ds.setUrl("jdbc:hsqldb:mem:."); // to get these configuration values
        ds.setUsername("sa");
        ds.setPassword("");
        return dataSource(ds.getUsername(),ds.getPassword(),ds.getUrl(),ds.getDriverClassName());
    }

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }
}


AppInitializer.java


public class AppInitializer implements WebApplicationInitializer {

    public void onStartup(ServletContext container) throws ServletException {

        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(AppConfig.class);
        ctx.setServletContext(container);


        ServletRegistration.Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.setLoadOnStartup(1);
        servlet.addMapping("/");
    }

}

PatientNameService.java

package com.vinay.patients.service;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.vinay.patients.db.PatientDAO;
import com.vinay.patients.config.AppConfig;

@Configuration
@EnableWebMvc
@Component
@ComponentScan(basePackages = "com.vinay.patients")
public class PatientNameService{
    @Autowired
    static AppConfig appConfig;
    static PatientDAO dao;

    public String getDocall() throws SQLException{
        ApplicationContext context;
        String Query ="";
        String username="";
        String password="";
        String url="";
        String classname ="";
        String doc_name="";
        Connection con = null;
        Statement  stmt = null;
        ResultSet result = null;
        //using config class to call the bean and collecting all the required parameters.
        context = new AnnotationConfigApplicationContext(AppConfig.class);
        DataSource dataSource = context.getBean(DataSource.class);
        Query = dao.getDocList();
        appConfig.dataSource(username, password, url,classname);
        try {
            Class.forName(classname);
            con = (Connection) DriverManager.getConnection(username,password,url);
            stmt = con.createStatement();
            result = stmt.executeQuery(Query);
            while(result.next()){
                doc_name= result.getString("Doc_Name").toString();
            }
         } catch (Exception e) {
            e.printStackTrace(System.out);
         }
        return doc_name;
    }
}

controller.java

 package com.vinay.patients.controller;

import java.sql.SQLException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.vinay.patients.service.PatientNameService;

@Controller
public class HelloController {
    @Autowired
    static PatientNameService PNservice ;
  /*  @RequestMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("name", "Viney Dhiman");
        return "welcome";
    }
    */

    @RequestMapping(value="/ViewDoc", method = RequestMethod.GET)
    public String data(Model model) throws SQLException {
        String all_Doc = PNservice.getDocall().toString();
        model.addAttribute("name", all_Doc);
        return "welcome";
    }
}

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>com.vinay.patients</groupId>
    <artifactId>Evidhi</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>Evidhi Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <properties>
        <java-version>1.7</java-version>
        <org.springframework-version>4.3.0.RELEASE</org.springframework-version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework-version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.2.4.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>1.8.0.10</version>
        </dependency>

    </dependencies>
    <build>
        <finalName>Evidhi</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>
</project>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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_3_0.xsd"
                        version="3.0">
    <display-name>Archetype Created Web Application</display-name>
</web-app>

您可以通过导入创建DataSource -> org.hsqldb.jdbc.JDBCDataSource;并在数据库配置中使用如下

private final static String URL_PATH = "jdbc:hsqldb:mem:test;sql.syntax_pgs=true";//test is your db name
private final static String USER_NAME = "sa";
private final static String PASS_WORD = "";

@Bean(name = "dataSource")
public JDBCDataSource getDataSource() {
    JDBCDataSource dataSource = new JDBCDataSource();
    dataSource.setUrl(URL_PATH);
    dataSource.setUser(USER_NAME);
    dataSource.setPassword(PASS_WORD);
    return dataSource;
}

您的代码在多个方面存在缺陷。

  1. 永远不要创建 ApplicationContext,因为您需要一个 bean,除非您想 运行 在内存、事务和难以调试的问题中。
  2. 您正在创建一个基于大量 String 参数的 DataSource,但忽略了这些方法参数的 @Value
  3. 有些东西要么是 @Configuration,要么是 @Component,但不能两者兼而有之。
  4. 您正在混合 Spring 版本 4.3 和 3.2 jar(永远不要混合任何框架的版本)。

混合Spring版本

在您的 pom 中,您定义了一个 属性 org.springframework-version 将其用于所有 org.springframework 依赖项以具有一致的版本。因此,也将其用于您的 spring-jdbc 依赖项。

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

不要创建 ApplicationContext

在你的代码中你做了很多事情,创建上下文,手动加载 jdbc 驱动程序等等。不要做任何这些。在您的服务中,您应该注入 DataSource 或更好的 JdbcTemplate.

@Service
public class PatientNameService{

    private final JdbcTemplate jdbc;

    public PatientNameService(JdbcTemplate jdbc) {
        this.jdbc=jdbc;
    }

    public String getDocall() throws SQLException{
        return jdbc.queryForString(<your-query-here>);
    }
}

没有创建 ApplicationContext,没有 DataSource 自己查找等。它现在也是一个 @Service,而不是混合搭配。

使用@ValueEnvironment获取属性

@Bean
public DataSource dataSource(String string, String string2, String string3, String string4) throws SQLException { ... }

这个签名告诉 Spring 创建一个 DataSource 并且为了创建它需要查找 String 类型的 5 个 bean,你得到的异常表明你没有有那些豆子(这并不奇怪,因为它们可能在 属性 文件中加载了 @PropertySource ,如果不应该的话。

现在您可以使用 @Value(...) 注释所有这些方法参数并指定名称或使用 Environment 检索它们。后者在使用大量属性时更容易。

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.vinay.patients")
@PropertySource("classpath:application.properties")
public class AppConfig extends WebMvcConfigurerAdapter {

    @Autowired
    private Environment env;

    @Bean
    public DataSource dataSource(){
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(env.getProperty("jdbc.driverClassName");
        ds.setUrl(env.getProperty("jdbc.url"); 
        ds.setUsername(env.getProperty("jdbc.username");
        ds.setPassword(env.getProperty("jdbc.password");
        return ds; 
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

注意 @PropertySource 这需要 class 路径的根目录中的 application.properties(即 src/main/resources 包含构建 [=15= 所需的 4 个属性].

还要注意 @Component 的删除,已经有一个 @Configuration 可以做同样的事情,甚至更多。