英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论