这似乎是一个明显的错误,但我无法找到它。以下是我的代码和配置:
申请类
@SpringBootApplication
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
SQL Config类
@Configuration
public class PostgreSQLConfig {
@Bean
public DataSource getDBDataSource() {
final DriverManagerDataSource driverManagerDataSource
= new DriverManagerDataSource(
"jdbc:postgresql://localhost:5432/applicationdb",
"username",
"password"
);
driverManagerDataSource.setDriverClassName("org.postgresql.Driver");
return driverManagerDataSource;
}
@Bean
public JdbcTemplate getJdbcTemplate(final DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
@Repository DAO CLASS
@Repository
public class CustomDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
.
.
@Component DAO Class
@Component
public class AnotherDAO {
@Autowired
private JdbcTemplate jdbcTemplate;
.
.
为JdbcTemplate
带注释的类填充@Component
对象。但是对于@Repository
带注释的类,该对象为null。我开始使用日志设置为DEBUG的spring boot,并且在创建JdbcTemplate
bean时找不到任何错误。从日志中,我可以推断出调用方法并创建bean。 JdbcTemplate
也引用了DataSource
。
如果@Repository
注释更改为@Component
,则代码可以正常工作。
@Repository
?@Component
一起使用却失败了
@Repository
?根据M. Deinum的建议,我做了以下更改。
PostgreSQLConfig
类application.properties
档案application.properties
spring.datasource.url=jdbc:postgresql://localhost:5432/applicationdb
spring.datasource.user=username
spring.datasource.password=password
spring.datasource.driver-class-name=org.postgresql.Driver
属性由spring应用程序加载。以下是日志消息:
2017-01-06 15:03:02 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'spring.datasource.driver-class-name' in [applicationConfigurationProperties] with type [String]
2017-01-06 15:03:02 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'spring.datasource.password' in [applicationConfigurationProperties] with type [String]
2017-01-06 15:03:02 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'spring.datasource.user' in [applicationConfigurationProperties] with type [String]
2017-01-06 15:03:02 [main] DEBUG o.s.c.e.PropertySourcesPropertyResolver - Found key 'spring.datasource.url' in [applicationConfigurationProperties] with type [String]
我收到一个例外。以下是详细信息:
2017-01-06 15:03:05 [main] DEBUG o.s.b.d.LoggingFailureAnalysisReporter - Application failed to start due to an exception
org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.jdbc.core.JdbcTemplate' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1474)
DAO类标有@Repository
注释。
的build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE'
}
}
apply plugin: 'java'
apply plugin: 'war'
apply plugin: 'idea'
apply plugin: 'application'
apply plugin: 'org.springframework.boot'
def applicationVersion = '0.0.1-SNAPSHOT'
def dependencyVersions = [
slf4j: '1.7.22',
logback: '1.1.8',
postgresql: '9.4.1212',
junit: '4.12'
]
group = 'com.appl'
version = applicationVersion
mainClassName = 'com.appl.Application'
war {
baseName = 'my-custom-appl'
version = applicationVersion
}
war.dependsOn test
repositories {
mavenCentral()
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
configurations.all {
exclude group: 'commons-logging', module: 'commons-logging'
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
compile 'org.springframework.boot:spring-boot-starter-jdbc'
compile 'org.springframework:spring-jdbc'
compile "org.slf4j:jcl-over-slf4j:${dependencyVersions.slf4j}"
compile "org.postgresql:postgresql:${dependencyVersions.postgresql}"
compile "ch.qos.logback:logback-classic:${dependencyVersions.logback}"
testCompile "junit:junit:${dependencyVersions.junit}"
testCompile 'org.springframework.boot:spring-boot-starter-test'
}
答案 0 :(得分:0)
我找到了问题解决方案(正在发生的一部分)。 DAO类中的方法标记为final
,而@Repository
不适用于final
方法。从日志中,我可以推断@Repository
尝试为DAO类创建代理,但代理失败。
当@Repository
替换为@Component
时,代码运行正常。再次从日志中,我可以看到@Component
没有创建代理,并且忽略了该方法的final
状态。
以下是Spring的调试日志:
当方法为final并且DAO Class被标记为@Repository
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Autowiring by type from bean name 'customDAO' via constructor to bean named 'getJdbcTemplate'
2017-01-08 09:19:03 [main] DEBUG c.j.l.d.CustomDAO - Received JdbcTemplate: org.springframework.jdbc.core.JdbcTemplate@3dedb4a6
2017-01-08 09:19:03 [main] INFO c.j.l.d.CustomDAO - Constructor Called
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'customDAO' to allow for resolving potential circular references
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.j.l.data.CustomDAO@19542407]
2017-01-08 09:19:03 [main] INFO o.s.aop.framework.CglibAopProxy - Unable to proxy method [public final int com.j.l.data.CustomDAO.persistEvent(java.util.List)] because it is final: All calls to this method via a proxy will NOT be routed to the target instance.
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Found 'equals' method: public boolean java.lang.Object.equals(java.lang.Object)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Unable to apply any optimisations to advised method: public java.lang.String java.lang.Object.toString()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Found 'hashCode' method: public native int java.lang.Object.hashCode()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Unable to apply any optimisations to advised method: protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.springframework.aop.Advisor)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.aopalliance.aop.Advice)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isFrozen()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setTargetSource(org.springframework.aop.TargetSource)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setExposeProxy(boolean)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isExposeProxy()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isProxyTargetClass()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract org.springframework.aop.TargetSource org.springframework.aop.framework.Advised.getTargetSource()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setPreFiltered(boolean)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isPreFiltered()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract java.lang.Class[] org.springframework.aop.framework.Advised.getProxiedInterfaces()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isInterfaceProxied(java.lang.Class)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract org.springframework.aop.Advisor[] org.springframework.aop.framework.Advised.getAdvisors()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvisor(org.springframework.aop.Advisor)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvice(org.aopalliance.aop.Advice)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract java.lang.String org.springframework.aop.framework.Advised.toProxyConfigString()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract java.lang.Class org.springframework.aop.TargetClassAware.getTargetClass()
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'customDAO'
当方法不是最终的并且DAO类被标记为@Repository
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'getJdbcTemplate'
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Autowiring by type from bean name 'anotherDAO' via constructor to bean named 'getJdbcTemplate'
2017-01-08 09:19:03 [main] DEBUG c.j.l.data.AnotherDAO - Received JdbcTemplate: org.springframework.jdbc.core.JdbcTemplate@3dedb4a6
2017-01-08 09:19:03 [main] INFO c.j.l.data.AnotherDAO - Constructor Called
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'anotherDAO' to allow for resolving potential circular references
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Creating CGLIB proxy: target source is SingletonTargetSource for target object [com.j.l.data.AnotherDAO@907f2b7]
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Unable to apply any optimisations to advised method: public void com.j.l.data.AnotherDAO.persistEvent(com.j.l.model.EmergencyUserResponse)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Found 'equals' method: public boolean java.lang.Object.equals(java.lang.Object)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Unable to apply any optimisations to advised method: public java.lang.String java.lang.Object.toString()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Found 'hashCode' method: public native int java.lang.Object.hashCode()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Unable to apply any optimisations to advised method: protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.springframework.aop.Advisor)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.aopalliance.aop.Advice)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isFrozen()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setTargetSource(org.springframework.aop.TargetSource)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setExposeProxy(boolean)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isExposeProxy()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isProxyTargetClass()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract org.springframework.aop.TargetSource org.springframework.aop.framework.Advised.getTargetSource()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setPreFiltered(boolean)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isPreFiltered()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract java.lang.Class[] org.springframework.aop.framework.Advised.getProxiedInterfaces()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isInterfaceProxied(java.lang.Class)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract org.springframework.aop.Advisor[] org.springframework.aop.framework.Advised.getAdvisors()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvisor(org.springframework.aop.Advisor)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvice(org.aopalliance.aop.Advice)
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract java.lang.String org.springframework.aop.framework.Advised.toProxyConfigString()
2017-01-08 09:19:03 [main] DEBUG o.s.aop.framework.CglibAopProxy - Method is declared on Advised interface: public abstract java.lang.Class org.springframework.aop.TargetClassAware.getTargetClass()
2017-01-08 09:19:03 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'anotherDAO'
当方法是final / not final并且DAO类被标记为@Component
2017-01-08 09:13:21 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Autowiring by type from bean name 'customDAO' via constructor to bean named 'getJdbcTemplate'
2017-01-08 09:13:21 [main] DEBUG c.j.l.d.CustomDAO - Received JdbcTemplate: org.springframework.jdbc.core.JdbcTemplate@67fe380b
2017-01-08 09:13:21 [main] INFO c.j.l.d.CustomDAO - Constructor Called
2017-01-08 09:13:21 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Eagerly caching bean 'customDAO' to allow for resolving potential circular references
2017-01-08 09:13:21 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.transaction.config.internalTransactionAdvisor'
2017-01-08 09:13:21 [main] DEBUG o.s.b.f.s.DefaultListableBeanFactory - Finished creating instance of bean 'customDAO'
我仍然无法理解为什么@Repository
会创建代理并@Component
跳过代理?有没有办法在DAO类上标记方法final
并使用@Repository
?
如果需要,我可以为此创建一个单独的问题。