Spring:在没有@Component的情况下使用@Autowired。

huangapple go评论76阅读模式
英文:

Spring: @Autowired without @Component

问题

在一个真实的项目中,我发现在以下代码中可以省略 @Component

// 没有 @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)?是否有任何官方文档说明这一点?

更新: 各位,项目中没有 @Configuration,也没有 XML 配置,我知道这些声明可以将类变成一个 bean,但问题不是关于它们。我甚至在上面的问题中写了“(也就是要成为一个 bean)”来涵盖这一点。@Autowired 在一个非 bean 类中是否有效?或者它是否会将使用它的类声明为一个 bean?

英文:

In a real project, I found out that @Component may be omitted in the following code:

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

    private final CustomerPreference customerPreference;

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

    // ...
}

@Component
public class CustomerPreference {...}

(The example is taken from the official Spring docs https://docs.spring.io/spring-framework/docs/4.3.x/spring-framework-reference/htmlsingle/#beans-autowired-annotation , and the docs show no @Component at all, which may mean either that it is not needed, or that it is just not shown.)

The project where I work does not use any XML bean declarations, but it uses frameworks other than just Spring, so it is possible that something declares the class as a bean. Or it may be a feature of the version of Spring that we use, and if that feature is not documented, it may be dropped later.

Question:
Must the class that uses @Autowired be annotated with @Component (well, be a bean)? Is there any official documentation about that?

UPD Folks, there is no @Configuration and no XML configs in the project, I know that such declarations make a bean from a class, but the question is not about them. I even wrote "(well, be a bean)" in the question above to cover that. Does @Autowired work in a class that is not a bean? Or maybe it declares the class that uses it as a bean?

答案1

得分: 4

根据 https://stackoverflow.com/a/3813725/755804 所述,使用 autowireBean(),确实可以从未声明为 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 不会假设使用 @Autowired 的类是 @Component

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

英文:

According to https://stackoverflow.com/a/3813725/755804 , with autowireBean() it is possible to autowire a bean from a class not declared as a bean.

@Autowired
private AutowireCapableBeanFactory beanFactory;

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

and

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);
    }
}

On the other hand, by default the latest Spring does not assume that classes that use @Autowire are @Component-s.

UPD
As to the mentioned real project, the stack trace shows that the constructor is called from createBean(). That is, the framework creates beans from classes declared in the framework's configs.

答案2

得分: 2

有几种在Spring中实例化bean的方式之一是使用@Component注解。通过这种方式,Spring将扫描所有已定义的组件扫描路径,并初始化所有带有@Component或使用它的注解(如Controller、Service等)的类。

另一种初始化bean的方式是使用配置类(带有@Configuration注解),该类包含使用@Bean注解的方法。每个这样的方法都将创建一个bean。

还有一种使用XML配置来创建bean的选项,但这种方法变得越来越不常见,因为基于注解的方法更加方便。

英文:

there are several ways to instantiate a bean in Spring.
One of them indeed is with the @Component annotations, with that, Spring will scan all the packages defined for component-scan and initialize all annotated classes (either with @Component or one of the annotations that uses it - Controller, Service, etc.).

Other way to initialise beans is using a configuration class (annotated with @Configuration) that includes methods annotated with @Bean. each of these methods will create a bean.

There's also an option to create the beans using xml configurations, but this is becoming less and less common, as the annotation-based approach is more convinient

huangapple
  • 本文由 发表于 2020年10月13日 21:02:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/64335862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定