我正在尝试使用spring4和datasource配置连接到数据库。我遵循一个教程,所以这是正确的配置:
package spittr.config;
import ...
@Configuration
public class DataConfig {
@Bean
public JndiObjectFactoryBean dataSource() {
JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean();
jndiObjectFB.setJndiName("java:jboss/datasources/jdbc/SpitterDS");
jndiObjectFB.setProxyInterface(javax.sql.DataSource.class);
return jndiObjectFB;
}
@Bean
public JdbcOperations jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
一切正常,但正如您所见,我返回的是jndiobjectfactorybean而不是datasource。如果我很好地理解spring(可能我不理解,否则我在这里会理解),如果您不指定bean名称,spring将把bean的名称设置为返回类型,第一个字母为小写。例如,下面的代码行将返回一个id为“myfantasticbean”的bean(小写为“m”)
@Bean
public MyFantasticBean createMyBean() {
return new MyFantasticBean();
}
我看到很多人在网上使用这个版本的dataconfig,其中方法datasource()返回一个datasource类型的对象(应该是这样的):
package spittr.config;
import ...
@Configuration
public class DataConfig {
@Bean
public DataSource dataSource() {
JndiObjectFactoryBean jndiObjectFB = new JndiObjectFactoryBean();
jndiObjectFB.setJndiName("java:jboss/datasources/jdbc/SpitterDS");
jndiObjectFB.setProxyInterface(javax.sql.DataSource.class);
return (DataSource) jndiObjectFB.getObject();
}
@Bean
public JdbcOperations jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
但如果使用此数据源创建,则会出现以下错误:
bin/content/10_SpringWeb_BE_JDBC.war/WEB-INF/classes/spittr/data/JdbcSpitterRepository.class"]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jdbcTemplate' defined in class path resource [spittr/config/DataConfig.class]: Bean instantia
tion via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.jdbc.core.JdbcOperations]: Factory method 'jdbcTemplate' threw exception; nested exception is java.lang.IllegalArgumentException: Property 'dataSource' is required
我甚至找到了解决方案,修改了datasource()方法,现在变成这样:
package spittr.config;
import ...
@Configuration
public class DataConfig {
@Bean
public DataSource dataSource(){
final JndiDataSourceLookup dsLookup = new JndiDataSourceLookup();
DataSource dataSource = dsLookup.getDataSource("java:jboss/datasources/jdbc/SpitterDS");
return dataSource;
}
@Bean
public JdbcOperations jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
但我真的不明白为什么这个有效而前一个无效。有人能解释一下我做错了什么吗?
非常感谢
1条答案
按热度按时间iyfamqjs1#
Spring按类型连接所有豆子。这意味着它将查找返回类型为的bean定义
DataSource
,当使用java配置时。这就是使用jndidatasourcelookup时的情况,这样spring就可以毫无问题地找到它。它不能从jndiobjectfactorybean派生数据源,除非在返回时强制转换它。另外,你在陈述的时候也有点搞错了
如果我很好地理解spring(可能我不理解,否则我在这里会理解),如果您不指定bean名称,spring将把bean的名称设置为返回类型,第一个字母为小写。例如,下面的代码行将返回一个id为“myfantasticbean”的bean(小写为“m”)
只有在使用组件扫描时才是这样。
因此,如果您有一个用@service等注解的类:
那么是的,这个名字将是myfantasticbean,因为这个名字不能从其他东西派生。重要的是要意识到,在使用java配置时,名称不会与类型相同。
在您的示例中,myfantasticbean是spring在您想要注入它时将搜索的bean类型。以及
createMyBean
将是bean的名称。因此,如果您有多个myfantasticbean类型的bean示例,那么您可以使用bean名称来指定要注入的bean。对你来说那就是