【问题标题】:Spring: @Autowired without @ComponentSpring:没有@Component的@Autowired
【发布时间】:2021-01-27 19:55:04
【问题描述】:

在一个真实的项目中,我发现@Component在下面的代码中可能会被省略:

// no @Component !!!!!
public class MovieRecommender {

    private final CustomerPreference customerPreference;

    @Autowired
    public MovieRecommender(CustomerPreference customerPreference) {
        this.customerPreference = customerPreference;
    }

    // ...
}

@Component
public class CustomerPreference {...}

(示例取自 Spring 官方文档 https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/htmlsingle/#beans-autowired-annotation ,文档根本没有显示 @Component,这可能意味着它不需要它,或者它只是没有显示。)

我工作的项目没有使用任何 XML bean 声明,但它使用了 Spring 以外的框架,因此有可能将类声明为 bean。或者它可能是我们使用的 Spring 版本的一个特性,如果该特性没有记录在案,它可能会在以后被删除。

问题: 使用@Autowired 的类必须用@Component 注释(好吧,是一个bean)?有相关的官方文档吗?

UPD 伙计们,项目中没有@Configuration 和XML 配置,我知道这样的声明会从一个类中生成一个bean,但问题不在于它们。我什至在上面的问题中写了 "(好吧,成为一个 bean)" 来涵盖这一点。 @Autowired 在不是 bean 的类中工作吗?或者它可能声明了将其用作 bean 的类?

【问题讨论】:

  • 好吧,如果你没有得到空指针异常,它似乎正在工作:)
  • 创建 Spring bean 有不同的方法。一种是将@Component 与类路径扫描一起使用,其他方法是使用XML 配置或Java 配置,在@Configuration 类中使用@Bean 方法。所以答案是:不,@Autowired 并不一定意味着你也必须使用@Component
  • 是的,它可以通过 @Configuration 类中的 @Bean 注释来完成,但是在构造函数上使用 @Autowired 似乎没有多大意义,因为在 Bean 定义中你必须逐字指定什么类你愿意在那里注入,所以不会有自动装配。 @OP:对我来说,在将此组件从基于注释的配置重构为基于 Java 的配置之后,似乎有人忘记从您的源代码中删除此注释。您是否尝试删除此@Autowire?顺便说一句。现代 IDE 应该有可能显示特定 bean 的注册位置。试试看吧
  • 可以用applicationContext.xml@Configuration+@Bean注册。
  • @Autowired 在上面的例子中构造没有意义... 在一个真实的项目中,我发现@Component 在下面的代码中可能会被省略 嗯,我不这么认为...

标签: java spring spring-boot


【解决方案1】:

根据https://stackoverflow.com/a/3813725/755804,使用autowireBean() 可以从未声明为 bean 的类中自动装配 bean。

@Autowired
private AutowireCapableBeanFactory beanFactory;

public void sayHello(){
    System.out.println("Hello World");
    Bar bar = new Bar();
    beanFactory.autowireBean(bar);
    bar.sayHello();
}

package com.example.demo;

import org.springframework.beans.factory.annotation.Autowired;

public class Bar {
    @Autowired
    private Foo foo;

    public void sayHello(){
        System.out.println("Bar: Hello World! foo="+foo);
    }
}

另一方面,默认情况下,最新的 Spring假定使用 @Autowire 的类是 @Component-s。

UPD 对于提到的实际项目,堆栈跟踪显示构造函数是从createBean() 调用的。也就是说,框架从框架配置中声明的类创建 bean。

【讨论】:

    【解决方案2】:

    有几种方法可以在 Spring 中实例化 bean。
    其中之一确实是带有@Component 注释,这样,Spring 将扫描为组件扫描定义的所有包并初始化所有带注释的类(使用@Component 或使用它的注释之一 - 控制器,服务,等等)。

    初始化 bean 的其他方法是使用配置类(用 @Configuration 注释),其中包括用 @Bean 注释的方法。这些方法中的每一个都将创建一个 bean。

    还有一个使用 xml 配置创建 bean 的选项,但这越来越不常见,因为基于注释的方法更方便

    【讨论】:

    • 项目中没有@Configuration,也没有xml,只有注释。没有单个@Bean。但是@Autowired 可以在没有@Component 的情况下工作。
    • @18446744073709551615 然后它会在某个地方注册,也许在其他一些上下文中,你扫描组件.. 注入不存在的 bean 是不可能的。没有办法。
    猜你喜欢
    • 2021-06-24
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2015-09-14
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多