【发布时间】:2017-04-02 22:08:54
【问题描述】:
我将从一个简单的例子开始。您有一个 Spring Boot 应用程序,它在初始化时运行 CommandLineRunner 类。
// MyCommandLineRunner.java
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
@Autowired //IntelliJ Warning
private DataSource ds;
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}
// Application.java
@SpringBootApplication
public class Application {
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner() {
return new MyCommandLineRunner();
}
}
现在,像这样,这行得通,一切正常。但是,IntelliJ 报告了@Autowired 所在位置的警告(我在评论中标记了位置)
Spring 团队建议: 始终在 bean 中使用基于构造函数的依赖注入。始终对强制依赖项使用断言。
现在如果我遵循这个,我有一个基于构造函数的依赖注入
@Autowired
public MyCommandLineRunner(DataSource ds) { ... }
这也意味着我也必须编辑Application.java,因为构造函数需要一个参数。在Application.java 中,如果我尝试使用setter 注入,我会得到同样的警告。如果我也重构它,我会得到一些我认为讨厌的代码。
// MyCommandLineRunner.java
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private DataSource ds;
@Autowired // Note that this line is practically useless now, since we're getting this value as a parameter from Application.java anyway.
public MyCommandLineRunner(DataSource ds) { this.ds = ds; }
@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}
// Application.java
@SpringBootApplication
public class Application {
private DataSource ds;
@Autowired
public Application(DataSource ds) { this.ds = ds; }
public static void main(String... args) {
SpringApplication.run(Application.class, args);
}
@Bean
public MyCommandLineRunner schedulerRunner() {
return new MyCommandLineRunner(ds);
}
}
上面的代码产生了相同的结果,但没有在 IntelliJ 中报告任何警告。 我很困惑,第二个代码比第一个更好吗?我是否遵循不正确的逻辑?这应该以不同的方式接线吗?
简而言之,正确的做法是什么?
注意DataSource 只是一个纯粹的例子,这个问题适用于任何被自动连接的东西。
注 2 只是说MyCommandLineRunner.java 不能有另一个空的构造函数,因为 DataSource 需要自动装配/初始化。会报错,不会编译。
【问题讨论】:
标签: java spring spring-boot coding-style autowired