Spring: @Autowired without @Component

Viewed 5777

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?

2 Answers

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

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.

Related