为什么自动装配 jdbctemplate 会导致循环依赖?
Why does autowiring jdbctemplate result in a cyclic dependency?
以下代码产生循环依赖错误。
@Controller
public class Controllers {
@Autowired
JdbcTemplate jdbcTemplate;
@RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public String map(){
String sql = "INSERT INTO persons " +
"(id, name, surname) VALUES (?, ?, ?)";
Connection conn = null;
jdbcTemplate.execute("INSERT INTO persons (id, name, surname) VALUES (1, \'Name\', \'Surname\')");
return "";
}
@Bean
@Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.username("root")
.password("root")
.url("jdbc:mysql://localhost:3306/people")
.driverClassName("com.mysql.jdbc.Driver")
.build();
}
The dependencies of some of the beans in the application context form a cycle:
| org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
↑ ↓
| controllers (field org.springframework.jdbc.core.JdbcTemplate controllers.Controllers.jdbcTemplate)
↑ ↓
| org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
↑ ↓
| dataSource
└─────┘
但如果我不自动装配 jdbctemplate 并正常初始化它
jdbcTemplate = new JdbcTemplate(dataSource());
那么不会产生错误
我有以下 gradle 依赖项:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.5.3.RELEASE")
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.2.RELEASE'
compile(group: 'mysql', name: 'mysql-connector-java', version: '6.0.6')
testCompile group: 'junit', name: 'junit', version: '4.12'
}
循环依赖背后的原因是什么?
你有一个循环依赖,因为 JdbcTemplate
需要一个 DataSource
但是要创建 DataSource
需要一个 Controllers
的实例,但是因为那个需要一个 JdbcTemplate
它无法构造(由于循环依赖)。
您正在使用 Spring 引导,但显然在努力不使用。删除 DataSource
的 @Bean
方法并将以下内容添加到 application.properties
.
spring.datasource.url=jdbc:mysql://localhost:3306/people
spring.datasource.username=root
spring.datasource.password=root
使用此 spring 启动将为您提供预配置的 DataSource
。
专业提示
您正在混合 Spring Boot 1.5.2 和 1.5.3 的其他版本永远不会混合框架的版本,因为那是等待发生的麻烦。只需删除所有版本,并假设您正确使用 Spring Boot with Gradle,您将拥有一个单一的托管版本。
以下代码产生循环依赖错误。
@Controller
public class Controllers {
@Autowired
JdbcTemplate jdbcTemplate;
@RequestMapping(value = "/", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody
public String map(){
String sql = "INSERT INTO persons " +
"(id, name, surname) VALUES (?, ?, ?)";
Connection conn = null;
jdbcTemplate.execute("INSERT INTO persons (id, name, surname) VALUES (1, \'Name\', \'Surname\')");
return "";
}
@Bean
@Primary
public DataSource dataSource() {
return DataSourceBuilder
.create()
.username("root")
.password("root")
.url("jdbc:mysql://localhost:3306/people")
.driverClassName("com.mysql.jdbc.Driver")
.build();
}
The dependencies of some of the beans in the application context form a cycle:
| org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration
↑ ↓
| controllers (field org.springframework.jdbc.core.JdbcTemplate controllers.Controllers.jdbcTemplate)
↑ ↓
| org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration
↑ ↓
| dataSource
└─────┘
但如果我不自动装配 jdbctemplate 并正常初始化它
jdbcTemplate = new JdbcTemplate(dataSource());
那么不会产生错误
我有以下 gradle 依赖项:
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.5.3.RELEASE")
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.2.RELEASE'
compile(group: 'mysql', name: 'mysql-connector-java', version: '6.0.6')
testCompile group: 'junit', name: 'junit', version: '4.12'
}
循环依赖背后的原因是什么?
你有一个循环依赖,因为 JdbcTemplate
需要一个 DataSource
但是要创建 DataSource
需要一个 Controllers
的实例,但是因为那个需要一个 JdbcTemplate
它无法构造(由于循环依赖)。
您正在使用 Spring 引导,但显然在努力不使用。删除 DataSource
的 @Bean
方法并将以下内容添加到 application.properties
.
spring.datasource.url=jdbc:mysql://localhost:3306/people
spring.datasource.username=root
spring.datasource.password=root
使用此 spring 启动将为您提供预配置的 DataSource
。
专业提示 您正在混合 Spring Boot 1.5.2 和 1.5.3 的其他版本永远不会混合框架的版本,因为那是等待发生的麻烦。只需删除所有版本,并假设您正确使用 Spring Boot with Gradle,您将拥有一个单一的托管版本。