【问题标题】:spring error No qualifying bean of type JdbcTemplatespring 错误没有 JdbcTemplate 类型的限定 bean
【发布时间】:2016-11-30 19:15:12
【问题描述】:

我有一个 Spring Boot 应用程序,我在我的配置中手动创建 DatasourceJdbcTemplate,因为我需要解密数据源密码。

我正在使用 Spring Boot 文档中推荐的 tomcat DataSource (org.apache.tomcat.jdbc.pool.DataSource),因为我正在配置连接属性。

我正在排除数据源的自动配置(请参阅Application.java),因为我是手动创建的。

Application.java

// exclude datasourceAutoConfiguration since we are creating manaully creating datasource bean in AppConfig
@SpringBootApplication
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

这是我的application.properties 文件

jdbc.hostdb.url=jdbc:jtds:sqlserver://hello-world:1122/foobar
host.jdbc.hostdb.username=foo
host.jdbc.hostdb.password=encryptedPassword
host.jdbc.hostdb.driver=net.sourceforge.jtds.jdbc.Driver
secret=afasdfansdfsdfsd

AppConfig.java

import org.apache.tomcat.jdbc.pool.DataSource;

@ComponentScan("com.company.foo")
public class AppConfig {


    @Value("${jdbc.hostdb.driver}")
    private String driver;

    @Value("${jdbc.hostdb.url}")
    private String url;

    @Value("${jdbc.hostdb.username}")
    private String user;

    @Value("${jdbc.hostdb.password}")
    private String pass;

    @Value("${secret}")
    private String secret;


    @Bean
    public DataSource datasource_mydb(Encryption encryption) {
        DataSource ds = new DataSource();
        ds.setDriverClassName(hostdb_driver);
        ds.setUrl(hostdb_url);
        ds.setUsername(hostdb_user);
        ds.setPassword(encryption.decrypt(hostdb_pass));
        return ds;
    }


    @Bean
    Encryption encryption() {
        return new Encryption(secret);
    }

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

}

MyRepository.java

@Repository
public class MyRepository {

    JdbcTemplate jdbcTemplate;

    @Autowired
    public MyRepository(JdbcTemplate jdbcTemplate){
        this.jdbcTemplate=jdbcTemplate;
    }
}

当我启动 spring 容器时,出现以下错误

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'MyRepository' defined in file [/Users//Documents/codebase/my-service/build/classes/main/com/company/foo/MyRepository.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.springframework.jdbc.core.JdbcTemplate]: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: 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 [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:185) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1143) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1046) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) ~[spring-context-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) ~[spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1185) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1174) [spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
    at com.concur.cognos.authentication.Application.main(Application.java:14) [main/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_102]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_102]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_102]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_102]
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144) [idea_rt.jar:na]
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741) ~[spring-beans-4.2.7.RELEASE.jar:4.2.7.RELEASE]
    ... 24 common frames omitted

2016-07-26 1

【问题讨论】:

  • 没有为 AppConfig 定义 bean。也许您打算用@Configuration 对其进行注释。
  • @SotiriosDelimanolis:是的,解决了它。我不知道我是怎么错过的。感谢收看
  • @SotiriosDelimanolis:我确实需要@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class}) 以避免自动配置,还是spring 看到我的数据源bean 而没有自动配置它?
  • @SotiriosDelimanolis:您可能对此有答案,stackoverflow.com/questions/38511755/…
  • 您不需要排除DataSourceAutoConfiguration,因为它足够聪明,可以看到您已经添加了DataSource。您也不需要创建JdbcTemplate,因为它会自动为您创建。所以你只需要创建DataSource

标签: spring spring-mvc spring-boot autowired


【解决方案1】:

问题在于您的 bean 定义的参数。他们的价值观从何而来?比如——

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

这里你没有指定dataSource 参数的值来自哪里。 datasource_mydb bean 的情况相同。在接受其他 bean 作为输入参数的 bean 定义上使用 @Autowire

@Bean
@Autowired
public DataSource datasource_mydb(Encryption encryption) {
    DataSource ds = new DataSource();
    ds.setDriverClassName(hostdb_driver);
    ds.setUrl(hostdb_url);
    ds.setUsername(hostdb_user);
    ds.setPassword(encryption.decrypt(hostdb_pass));
    return ds;
}


@Bean
Encryption encryption() {
    return new Encryption(secret);
}

@Bean
@Autowired
@Qualifier("datasource_mydb")
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
    return new JdbcTemplate(dataSource);
}

【讨论】:

  • 我认为没有必要。 @SotiriosDelimanolis 你怎么看?
  • 不,这根本没有必要。 @brainstorm Spring 将通过检查相应 bean 的上下文来解析 @Bean 方法的参数。您已经定义了一个名为 datasource_mydbDataSource bean,因此它可用于 JdbcTemplate bean 方法。
  • @SotiriosDelimanolis 和文档链接来验证这一点?如果是这种情况,那么 OP 错误的原因是 bean 的名称“datasource_mydb”没有按名称“dataSource”映射。
  • Here's the official doc on this process。注射不会在这里按名称发生。它按类型发生。
【解决方案2】:

有可能……
您可能没有在项目配置文件(.xml 文件)中添加 JdbcTemplate 依赖项。

【讨论】:

    【解决方案3】:

    请对 DataSource 和 JdbcTemplate 使用 spring 依赖项。之后,您可以自动装配 DataSource 和 JdbcTemplate。希望它会起作用。

    【讨论】:

      猜你喜欢
      • 2020-07-05
      • 1970-01-01
      • 2015-03-27
      • 2016-11-17
      • 1970-01-01
      • 1970-01-01
      • 2019-03-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多