Dear Spring Team

I have been working with Spring Boot for a few years now, and I just wanted to share two issues I have come across quite a few times that might be avoidable with some adjustments.

The @Autowired annotation used for field injection is widely not recommended, and even IntelliJ gives a warning when you use it.

  • https://www.quora.com/Is-autowired-annotation-deprecated
  • https://www.linkedin.com/pulse/you-should-stop-using-spring-autowired-felix-coutinho

Also, the use of the annotation on the top of a constructor has become unnecessary with newer Spring versions. Generally, I can not tell any advantage that this annotation has except its further capabilities, like optional dependencies (with "required = false"). Would it be a good idea to make the annotation officially deprecated for removal for these unnecessary usages I have mentioned, in order to discourage especially inexperienced developers? I have worked with some rookies now and then; they are usually the most likely to use the annotation for field injection, and you have to explain it every time. I also do not completely agree with the argument that it's more concise with field injection, because for such purposes there is either Lombok or Kotlin, both of which work like a charm and are even more compact than the annotation.

What I have also noticed is that there is very little documentation for the Spring GraphQL client, and at the beginning, I struggled quite a bit with all the things that you have to know when using it. The only thing I have really found was a good but superficial description by Dan Vega: https://www.danvega.dev/blog/graphql-client Would it be possible to make this documentation a bit more detailed? Maybe some examples of all the capabilities of the client could really help. Let me know if any of my assertions are wrong or if I have not considered something correctly. I generally appreciate Spring for what it is. Feel free to prioritise this issue, since it is just something I wanted to share and not something I am desperately asking for.

Thank you in advance for considering my request.

Best regards Johannes

Comment From: bclozel

Thanks for this report @jzelAdmin2006 - about the Spring GraphQL client, this project lives in another repository and so does its reference documentation. We do cover the GraphQL client support already in the reference documentation - can you create a new issue in https://github.com/spring-projects/spring-graphql and let us know what is missing?

Comment From: quaff

Would it be a good idea to make the annotation officially deprecated for removal

Please don't, at least there are two disadvantages of constructor injection: 1. Test class doesn't support constructor injection: org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter 2. The constructor is cumbersome if arguments are too many, reorder the arguments is not convenient as field injection

Comment From: snicoll

@jzelAdmin2006 going forward please refrain from creating an enhancement request with multiple unrelated topics.

The idea to deprecate @Autowired is not practical for many reasons. I don't believe that deprecating and then ultimately remove it will have a net positive impact on the community. As stated previously, it's fair to use in tests (@quaff you're wrong with 1. You need to add @Autowired to your parameter as JUnit handles the test instantiation, not spring). We also have a track record of making sure folks can upgrade and there are a lot of apps out there that use @Autowired in various legitimate places.

Our role is to guide users and work with tools. That's why IntelliJ IDEA warns you when you use field injection in production code. As for inexperience developer, there are many things that need to be taught and I am pretty convinced removing the annotation will not avoid conversation about dependency injection and how to structure it.

All in all, I disagree with the rationale and we can't certainly deprecate @Autowired. Thanks for the suggestion, in any case.

Comment From: quaff

You need to add @Autowired to your parameter as JUnit handles the test instantiation, not spring

OK, It works with explicit constructor injection, is it possible to support both implicit and explicit constructor injection?

Comment From: sbrannen

OK, It works with explicit constructor injection, is it possible to support both implicit and explicit constructor injection?

@quaff, please read the Dependency Injection with the SpringExtension section of the reference manual for details.

Comment From: quaff

OK, It works with explicit constructor injection, is it possible to support both implicit and explicit constructor injection?

@quaff, please read the Dependency Injection with the SpringExtension section of the reference manual for details.

Thanks for the link, I learned that implicit constructor injection need test class be annotated with @TestConstructor(autowireMode = AutowireMode.ALL):

@SpringJUnitConfig
@ContextConfiguration(classes = ConstructorInjectTests.class)
@TestConstructor(autowireMode = AutowireMode.ALL)
public class ConstructorInjectTests {

    public ConstructorInjectTests(Environment env) {

    }

    @Test
    void test() {
    }

}

Would it be better make autowireMode defaults to ALL, then we can inject Environment and other beans like ApplicationContext which doesn't need @TestConstructor, that's idiomatic for typical spring application.

Comment From: sbrannen

Would it be better make autowireMode defaults to ALL, then we can inject Environment and other beans like ApplicationContext which doesn't need @TestConstructor, that's idiomatic for typical spring application.

No. That would have been a breaking change.

Are you sure you read the entire section I linked?

See @TestConstructor for details on the use of @TestConstructor and how to change the global test constructor autowire mode.

You can change the default to ALL for your project if you so desire.

Comment From: quaff

No. That would have been a breaking change.

I understand it's a breaking change, I suggest changing it in major release if there is no technical limitation.

Are you sure you read the entire section I linked?

Yes I read that need extra system property, most people doesn't know @TestConstructor then they wouldn't know that way.