2

I have a small question. If the class is annotated with @Component, @Service, @Controller or @Repository and I want to inject its dependency, do I need @Autowired?

@RestController
@RequestMapping(value = "/goods", produces = APPLICATION_JSON_VALUE)
@SuppressWarnings("squid:S4684")
public class UserDeviceRestController implements UserDeviceRestApi {

  private final UserDeviceService userDeviceService;

  public UserDeviceRestController(UserDeviceService userDeviceService) {
    this.userDeviceService = userDeviceService;
  }

This code works perfect for me because it is @Service annotation specified in UserDeviceService. Is it because of that?

If I would have a class without one of this annotations (bolded), I assume I have to @Autowired it in constructor/field/setter then... So why not to specify @Component above all the possible dependency injected classes and do not remember about @Autowired

Thanks for hints

duffymo
  • 305,152
  • 44
  • 369
  • 561
Ernesto
  • 950
  • 1
  • 14
  • 31
  • 1
    I would add the Autowired annotation to the constructor and Qualifier annotation to each argument to spell out which bean is wanted. – duffymo Feb 06 '20 at 13:07
  • 1
    In newer versions of Spring, the `@Autowired` annotation is not required in this case. Spring is smart enough to understand from the constructor of your class `UserDeviceRestController` that it should look for a `UserDeviceService` bean to pass it. – Jesper Feb 06 '20 at 13:10
  • Spring considers all `@Component` annotated classes as beans and makes them ready for injection. I would use `@Autowired` for those fields that's sparsely used as a dependency. – freakomonk Feb 06 '20 at 13:14
  • For the Component thing ...RestController is a Component ... because RestController inherit from Controller and Controller is a Component. For autowired see here https://stackoverflow.com/questions/41092751/spring-injects-dependencies-in-constructor-without-autowired-annotation – pL4Gu33 Feb 06 '20 at 13:14
  • Since Spring 4.x you do not have to do it if you have one matching constructor. In case of multiple constructors you will have to annotate one of them with `@Autowired` to avoid exception which will be thrown when context is being raised/ – Michał Krzywański Feb 06 '20 at 13:16
  • 1
    @michalk Since Spring 4.3 to be more precise: https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#beans-autowired-annotation – Planck Constant Feb 06 '20 at 13:19
  • I am a Spring user since 1.0, so perhaps old habits die hard. Thanks to @Jesper for correctly pointing out that newer versions of Spring don't require it. I might still add it out of habit and for the sake of readability and consistency. It clarifies for me what the intended dependencies are. – duffymo Feb 06 '20 at 16:19

2 Answers2

3

If you have only one constructor you don't need @Autowired. If you have more than one you have to say to String which exactly constructor should be used. In this case, @Autowired is needed.

dehasi
  • 2,644
  • 1
  • 19
  • 31
1

@Autowired by default uses field injection. You need not to write that constructor or any setter for it. Just having any of the annotation that you have mentioned will work. So all of these annotation will make the beans of the class. Here are the details what these annotation do.

 @Component is a generic stereotype for any Spring-managed component or bean. 
    @Repository is a stereotype for the persistence layer.
    @Service is a stereotype for the service layer.
    @Controller is a stereotype for the presentation layer (spring-MVC).

From Spring 4.3 annotations are not required for constructor injection.

checkout this post Spring inject without autowire annotation

Silverfang
  • 349
  • 1
  • 8