【问题标题】:What is the difference between "constructor based injection" and " autowire by constructor mode" in SpringSpring中“基于构造函数的注入”和“通过构造函数模式自动装配”有什么区别
【发布时间】:2026-01-20 05:30:01
【问题描述】:

我知道并理解基于构造函数的注入。但是,自动装配模式让我感到困惑。 1) 我读过自动装配的默认模式是“不自动装配”,即我们必须手动设置 xml 文件中的属性。但是,基于 xml 的配置不是一种自动装配吗?如何将其视为“无自动装配”? 2) 其他自动装配模式是 i) byName ii) byType iii)constructor iv) auto-detect。我是否正确假设以下内容:

a) 当使用基于 xml 配置的自动装配时,默认模式是 'byName'(即我必须保持属性引用的名称与用作属性的 bean 的名称相同。)

b) 使用 Annotations 时,默认模式为 'byType'(无论 @Autowired 关键字放在哪里,即在 setter、构造函数或属性上,它都会搜索正在自动写入的属性的类型)

3) 基于构造函数的注入和自动装配的“构造函数”模式有什么区别?(我已经读过构造函数模式意味着它在所有构造函数参数上应用 byType 模式,但它与放置 @Autowired 关键字有什么不同呢?构造函数)

4) 我知道要在注解中启用自动装配模式 byName,在 xml 文件的 bean 定义中,我必须使用“autowire = 'byName'”。但是,假设我只使用 Annotations 配置(使用@Component,并且在 xml 中没有 bean 定义),并且我想使用 byName 自动装配模式,那么这样做的方法是什么?

【问题讨论】:

    标签: spring autowired


    【解决方案1】:

    我觉得你有点困惑。首先,您需要了解依赖注入(请参阅here)。关于 DI 的信息很多,但简而言之,这意味着某些第三方(例如 Spring IOC)将依赖项传递给对象,而不是对象自己创建/获取引用。这可以通过构造函数或设置器发生。例如,考虑构造函数 DI

    class B{
    }
    
    class A{
      private B b;
      public A(B b){
        this.b = b;
      } 
    } 
    

    某些第三方会将 B 类的实例注入 A 中,而不是 A 类创建对 B 本身的引用。很多时候你会使用一个接口,所以类 A 甚至不知道将注入什么对象。

    现在在 Spring 中有不同的方法来配置对象之间的这些关联(上面的示例)。您可以使用 XML、Java 配置或自动装配。他们是独立的,但做同样的事情。

    在 XML 和 JAVA 配置中,您需要显式配置依赖项 - 在 xml 文件中或为 JAVA 配置提供 @Configuration 类并使用 @Bean 注释 bean。自动装配是不同的。在那里,您可以创建简单的 POJO,并使用 @Component、@Controller、@Service 或 @Repository 进行注释。它们将通过组件扫描自动注册为 bean。通过自动装配,您无需在 XML 文件或 JAVA Config 类中显式配置依赖项。您可以直接在代码中执行此操作。例如,如果我们必须使用前面的示例来比较 java config 和 autowiring

    Java Config (explicit config in a config class)
    
    @Bean
    public A getA(){
      return new A(new B());
    }
    
    Autowiring (implicit - done in code)
    
       @Component 
       class B{
       }
    
    @Component
    class A{
      private B b;
    
      @Autowired
      public A(B b){
        this.b = b;
      } 
    } 
    

    在后者中,我们将 B 类自动连接到 A 类(由于 @Component 注释,它们都将注册为 bean),而无需在 xml 文件或 java 配置类中明确定义此关联。我希望这是有道理的。

    【讨论】:

    • 了解两者之间的区别非常有帮助。谢谢。 UserF40 和你澄清了我的大部分问题。剩下一对。我假设构造函数自动装配是实现基于构造函数的注入的一种方式是否正确?另外,你能告诉我如何使用注释而不是xml来使用自动检测自动装配模式吗?
    • 再问一个问题,你会得到回应,让其他人受益
    • 好的。会做的。谢谢。
    【解决方案2】:

    如果您必须在 xml 中指定 bean 名称,它不会自动发生,因此它不会自动装配。

    使用自动装配,即使可能没有明确写入,spring 也会确定要注入的 bean。

    使用基于xml配置的自动装配时,默认模式为'byName'

    使用注解时,发生的顺序取决于所使用的注解,因为有几个注解可以使用。 @Autowire@Resource@Inject.

    当使用@Component 时,默认接线是类型。下面的方法将解决服务对象的任何自动装配需求。

    @Bean
    public Service getMyService(){
    return new Service();
    }
    

    如果有多个 @Bean 方法返回一个服务,你会得到一个错误。

    如果您想在使用@Component 时通过名称进行连接,您可以将@Qualifier("nameToUse") 注释添加到变量中。它将找到一个名为getNameToUse()@Bean 注释方法。

    @Autowired
    @Qualifier("nameToUse")
    private Service myService;
    

    【讨论】:

    • 好的,所以,我知道当我们使用基于 xml 的配置时,它不是自动装配的。但是假设,我使用 xml 配置进行 bean 定义和注释进行自动装配(即我没有使用 @组件、@Service 等)现在,如果我将 @Autowired 关键字放在属性声明上,它是按类型吗?如果我将它放在构造函数或设置器上会怎样? (请注意,我不是在询问基于 setter/constructor 的注入)这是我关注的链接:howtodoinjava.com/spring/spring-core/… 另外:journaldev.com/2623/spring-autowired-annotation
    • 正如答案中提到的@Autowire 是按类型优先
    • 那么,'autowire by constructor' 模式是什么意思?我了解 byName 和 byType 模式,但不了解其他两种模式,即:'按构造函数'和'自动检测'。上面的链接中提到了这些。
    • 构造函数意味着不注释类属性而是构造函数参数。自动检测就像扫描 Spring 将在哪里计算出候选 bean。
    • 因此,通过构造函数自动装配是实现基于构造函数的注入的一种方式。这个说法正确吗?另外,你能告诉我如何使用注释启用自动检测模式,而不是在 xml 中提及吗?