2016-07-27 5 views
0

У меня есть приложение загрузки весны, где я создаю Datasource и JdbcTemplate вручную в моей конфигурации, потому что мне нужно расшифровать пароль источника данных.ошибка пружины Нет подходящего компонента типа JdbcTemplate

Я использую 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; 
    } 
} 

, когда я начинаю пружинный контейнер, я получаю следующую ошибку

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 
+1

Для 'AppConfig' не существует компонента. Возможно, вы хотели аннотировать его с помощью '@ Configuration'. –

+0

@SotiriosDelimanolis: да, это исправлено. Я не знаю, как я это пропустил. Спасибо, что поймали его –

+0

@SotiriosDelimanolis: мне нужно '@EnableAutoConfiguration (exclude = {DataSourceAutoConfiguration.class})', чтобы избежать автоконфигурации, или весна не видит мой источник данных, а не автоконфигурирует его? –

ответ

-1

Если добавить @Autowired в

JdbcTemplate jdbcTemplate; 

в MyRepository классе, то он будет работать ,

Ниже приведена подсказка из вашего исключения.

org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.jdbc.core.JdbcTemplate] found for dependency 
+0

нет. Я сначала попробовал это. это не работает. и, следовательно, я перешел на конструкторскую инъекцию на основе этой публикации. Http: // StackOverflow.com/questions/26933286/spring-load-component-before-the-needed-bean –

0

Проблема заключается в аргументах ваших определений компонентов. Откуда взялись бы их ценности? Например -

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

Здесь вы не указали, где бы значение dataSource аргумента берутся. Тот же случай datasource_mydb bean. Используйте @Autowire для определения bean-компонентов в качестве входных аргументов.

@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); 
} 
+0

Я не думаю, что это необходимо. @SotiriosDelimanolis, что вы думаете? –

+2

Нет, это совсем не обязательно. @brainstorm Spring разрешит аргументы для методов '@ Bean', проверив контекст для соответствующих компонентов. Вы определили компонент 'DataSource' с именем' datasource_mydb' и поэтому он доступен для метода bean-компонента JdbcTemplate. –

+0

@SotiriosDelimanolis и ссылка doc для подтверждения этого? Если это так, причиной ошибки OP является имя bean's «datasource_mydb», которое не отображается по имени «dataSource». –