Spring在手动类实例化期间注入@Autowired字段

ale*_*oid 5 java spring

在我的项目中,我很惊讶地看到Spring(4.3)似乎试图自动绑定类的依赖关系,即使它们是手动实例化的。

MyClass.java (请注意龙目岛注释):

@NoArgsConstructor
@AllArgsConstructor
public class MyClass {
    @Autowired
    private MyClassDependency dependency;
}
Run Code Online (Sandbox Code Playgroud)

MyClassDependency.java 使用工厂方法并且没有Spring注释:

public class MyClassDependency {
    public static MyClassDependency create() { return new MyClassDependency(); }
}
Run Code Online (Sandbox Code Playgroud)

Spring配置导致NoSuchBeanDefinitionException

@Configuration
public class SpringConfig {
    @Bean
    public MyClass myClass() {
        return new MyClass(MyClassDependency.create());
    }
}
Run Code Online (Sandbox Code Playgroud)

提供bean使Spring感到高兴:

@Configuration
public class SpringConfig {
    @Bean
    public MyClass myClass() {
        return new MyClass(); // let autowire inject dependencies
    }
    @Bean
    public MyClassDependency myClassDependency() {
        return MyClassDependency.create();
    }
}
Run Code Online (Sandbox Code Playgroud)

这对我来说是一个很大的惊喜。我想要配置的第一个简单版本...此行为来自/受控制的地方在哪里?(有可能我错过了它或将其从某些依赖项中删除了)。

PS:为澄清起见,MyClass代码不在我的控制范围内,但是我可以更改Spring配置。我想了解Spring如何通过bean方法拦截构造函数调用,以及是否可以代替使用构造函数。

小智 3

问题如下:

  1. 您用@Autowired注释了一个字段 - 它告诉Spring,有一个依赖项需要在那里注入
  2. 您使用 @Bean 注释了一个方法 - 它将返回值放入 Spring 的上下文中。
  3. 当 Spring 处理 @Bean 注释对象的返回值时,它开始处理其注释 - 并且有一个带有注释的字段,它告诉 Spring 在那里注入依赖项,即使该字段已经分配了值。
  4. Spring 尝试在此处注入依赖项,但该依赖项在 Spring 上下文中不存在,因此注入失败。

因此,拥有 @Bean,但手动注入 @Autowired 依赖项会相互冲突,您现在可能明白了,为什么 - 您不应该手动注入 Autowired beans!Autowired 是一个注释,告诉 CI 容器执行一些注入工作。