19

I find some answer: https://stackoverflow.com/a/21218921/2754014 about Dependency Injection. There isn't any annotation like @Autowired, @Inject or @Resource. let's assume that there isn't any XML configuration for this example TwoInjectionStyles bean (except simple <context:component-scan base-package="com.example" />.

Is it correct to inject without specify annotation?

kuba44
  • 1,838
  • 9
  • 34
  • 62

2 Answers2

26

From Spring 4.3 annotations are not required for constructor injection.

public class MovieRecommender {

    private CustomerPreferenceDao customerPreferenceDao;

    private MovieCatalog movieCatalog;

    //@Autowired - no longer necessary
    public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
        this.customerPreferenceDao = customerPreferenceDao;
    }

    @Autowired 
    public setMovieCatalog(MovieCatalog movieCatalog) {
        this.movieCatalog = movieCatalog;
    }
}

But you still need @Autowired for setter injection. I checked a moment ago with Spring Boot 1.5.7 (using Spring 4.3.11) and when I removed @Autowired then bean was not injected.

Krzysztof Atłasik
  • 21,985
  • 6
  • 54
  • 76
  • So this anwser https://stackoverflow.com/a/21218921/2754014 is not correct? – kuba44 Oct 02 '17 at 12:13
  • 2
    Unless I missed something, won't work. So your're right, without any xml configuration this answer is incorrect. – Krzysztof Atłasik Oct 02 '17 at 15:08
  • 1
    This official example is kind of misleading me. I thought setter injection would work without @Autowired if it has a no-arg constructor. https://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#beans-setter-injection – Anderson Aug 24 '20 at 08:41
14

Yes, example is correct (starting from Spring 4.3 release). According to the documentation (this for ex), if a bean has single constructor, @Autowired annotation can be omitted.

But there are several nuances:

1. When single constructor is present and setter is marked with @Autowired annotation, than both constructor & setter injection will be performed one after another:

@Component
public class TwoInjectionStyles {
    private Foo foo;

    public TwoInjectionStyles(Foo f) {
        this.foo = f; //Called firstly
    }

    @Autowired
    public void setFoo(Foo f) { 
        this.foo = f; //Called secondly
    }
}

2. At the other hand, if there is no @Autowire at all (as in your example), than f object will be injected once via constructor, and setter can be used in it's common way without any injections.

Alex Saunin
  • 976
  • 1
  • 8
  • 15