java - 为什么 Spring 框架不记录 Autowiring Setter 注入(inject)?

标签 java spring spring-boot spring-mvc

我是 Spring 新手,目前正在学习依赖注入(inject)。我正在使用 Spring Boot 2.2.2

如果我使用基于构造函数的指令,我会在日志中看到它正在 Autowiring 。

这是我的代码:

// Sorting an array
@Autowired
private SortAlgrithm sortAlgorithm;
//^Tell Spring this is a dependency

public BinarySearchImpl(SortAlgrithm sortAlgorithm) {
    super();
    this.sortAlgorithm = sortAlgorithm;
}

这是我的日志,它反射(reflect)了 Spring 处理的 Autowiring 过程:

2020-01-04 20:34:30.435 DEBUG 10396 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'springIn10StepsApplication'
2020-01-04 20:34:30.441 DEBUG 10396 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'binarySearchImpl'
2020-01-04 20:34:30.446 DEBUG 10396 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'bubbleSortAlgorithm'
2020-01-04 20:34:30.447 DEBUG 10396 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Autowiring by type from bean name 'binarySearchImpl' via constructor to bean named 'bubbleSortAlgorithm'

现在,如果我使用 setter 注入(inject)稍微更改代码:

    private SortAlgorithm sortAlgorithm;

    // Setter injection
    @Autowired
    public void setSortAlgorithm(SortAlgorithm sortAlgorithm) {
        System.out.println("setter called");
        this.sortAlgorithm = sortAlgorithm;
    }

并提供日志:

2020-01-04 20:37:23.853 DEBUG 7600 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'org.springframework.boot.context.internalConfigurationPropertiesBinderFactory'
2020-01-04 20:37:23.858 DEBUG 7600 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'springIn10StepsApplication'
2020-01-04 20:37:23.863 DEBUG 7600 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'binarySearchImpl'
2020-01-04 20:37:23.870 DEBUG 7600 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Creating shared instance of singleton bean 'bubbleSortAlgorithm'
setter called

我包含了要打印出来的“setter called”,以让我知道正在调用 setter 注入(inject),因为它没有包含在日志中。我想知道这是否是 Spring 的侥幸,以及其他人是否也经历过同样的事情。我知道我的 bean 是在应用程序上下文中管理的,并且在运行时,Spring 正在寻找依赖项。 @Autowire 告诉 Spring 我的依赖项是什么并适本地注入(inject)。第一个日志代表该行为。但是,事实上“setter called”被打印出来,我想知道这是否意味着Spring正在通过调用setter方法来执行 Autowiring ,即使它没有反射(reflect)在日志中。

最佳答案

在第一种情况下,setter 注入(inject)甚至没有被触发,它的构造函数注入(inject)就在那里发生,因此没有日志。

来自docs

Autowired Constructors :

.....

If a class only declares a single constructor to begin with, it will always be used, even if not annotated. An annotated constructor does not have to be public.

例如,如果你有这样的东西:

@Component
public class TestAbd {

    @Autowired
    private OtpService otpService;

    public TestAbd(OtpService otpService) {
        System.out.println("Setting OTP service thorugh constructor injection.");
        this.otpService = otpService;
    }

    public void setOtpService(OtpService otpService) {
        System.out.println("Setting OTP service thorugh setter injection.");
        this.otpService = otpService;
    }

}

您将拥有以下日志

...

Setting OTP service thorugh constructor injection.
2020-01-05 10:44:50:743 [main] 

...

因此,在第一种情况下,由于您声明了一个构造函数,因此它将始终用于设置依赖项,因此会跳过整个 setter 注入(inject)。

关于java - 为什么 Spring 框架不记录 Autowiring Setter 注入(inject)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59597116/

相关文章:

java - 如何在jquery ajax脚本中转换为所需的日期格式

java - Spring 应用程序没有响应

spring - 使用curl测试时,Grails Spring Security Rest未经授权(401)

spring-boot - 如何使Spring/Gradle识别JdbcTemplate初始化

java - E/AndroidRuntime(29668): java. lang.RuntimeException:无法启动 Activity ComponentInfo {错误膨胀类 fragment

Java:地址已被使用

java - 无法将 MS Sql 查询转换为 Hibernate @Query

Java Mockito 无法模拟方法的结果

java - Spring中如何从@Autowired List<>的每个bean中获取@Qualifier

java - Java Spring Boot MongoDB 中的软删除