gpt4 book ai didi

java - 干净的代码 - 应该在哪里应用 @Autowired?

转载 作者:IT老高 更新时间:2023-10-28 13:59:28 26 4
gpt4 key购买 nike

我将从一个简单的例子开始。您有一个在初始化时运行 CommandLineRunner 类的 Spring 启动应用程序。

// 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 team recommends: Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies.

现在如果我遵循这个,我有一个基于构造函数的依赖注入(inject)

@Autowired
public MyCommandLineRunner(DataSource ds) { ... }

这也意味着我还必须编辑 Application.java,因为构造函数需要一个参数。在 Application.java 如果我尝试使用 setter 注入(inject),我会得到同样的警告。如果我也重构它,我会得到一些我认为讨厌的代码。

// 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 中报告任何警告。我很困惑,第二个代码比第一个更好吗?我是否遵循不正确的逻辑?这应该以不同的方式接线吗?

简而言之,正确的做法是什么?

note DataSource 只是一个纯粹的例子,这个问题适用于任何被自动连接的东西。

注 2 只是说 MyCommandLineRunner.java 不能有另一个空的构造函数,因为 DataSource 需要 Autowiring /初始化。会报错,不会编译。

最佳答案

有几种方法可以改进它。

  1. 您可以删除 @Autowired来自您的MyCommandLineRunner因为你让 @Bean方法构造它的一个实例。注入(inject)DataSource直接作为参数传入方法中。

  2. 或删除@Autowired并删除 @Bean并拍打@Component您的 MyCommandLineRunner 上的注释检测并删除工厂方法。

  3. 内联你的MyCommandLineRunner在你的@Bean方法作为 lambda。

MyCommandLineRunner 中没有 Autowiring

public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private final DataSource ds;

public MyCommandLineRunner(DataSource ds) { this.ds = ds; }

@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}

还有应用程序类。

@SpringBootApplication
public class Application {

public static void main(String... args) {
SpringApplication.run(Application.class, args);
}

@Bean
public MyCommandLineRunner schedulerRunner(DataSource ds) {
return new MyCommandLineRunner(ds);
}
}

@Component 的使用

@Component
public class MyCommandLineRunner implements CommandLineRunner {
private final Log logger = LogFactory.getLog(getClass());
private final DataSource ds;

public MyCommandLineRunner(DataSource ds) { this.ds = ds; }

@Override
public void run(String... args) throws Exception {
logger.info("DataSource: " + ds.toString());
}
}

还有应用程序类。

@SpringBootApplication
public class Application {

public static void main(String... args) {
SpringApplication.run(Application.class, args);
}

}

内联 CommandLineRunner

@SpringBootApplication
public class Application {

private static final Logger logger = LoggerFactory.getLogger(Application.class)

public static void main(String... args) {
SpringApplication.run(Application.class, args);
}

@Bean
public MyCommandLineRunner schedulerRunner(DataSource ds) {
return (args) -> (logger.info("DataSource: {}", ds);
}
}

所有这些都是构建实例的有效方法。用哪一种,用你觉得舒服的那一种。还有更多选项(此处提到的所有变体)。

关于java - 干净的代码 - 应该在哪里应用 @Autowired?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43174074/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com