Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring should tolerate zero-argument constructors with javax.inject.Inject [SPR-15005] #19572

Closed
spring-projects-issues opened this issue Dec 12, 2016 · 4 comments
Assignees
Milestone

Comments

@spring-projects-issues
Copy link
Collaborator

@spring-projects-issues spring-projects-issues commented Dec 12, 2016

Greg Methvin opened SPR-15005 and commented

According to https://docs.oracle.com/javaee/6/api/javax/inject/Inject.html, "injectable constructors are annotated with @Inject and accept zero or more dependencies as arguments". However, when you try to use @Inject with a zero-argument constructor, you receive an IllegalStateException: "Autowired annotation requires at least one argument".

In other words, @Autowired requires at least one argument in the constructor, and @Inject requires at least zero. Spring attempts to support the @Inject annotation by treating it as equivalent to @Autowired (see https://github.com/spring-projects/spring-framework/blob/v5.0.0.M3/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java#L149), but full support requires supporting zero-argument constructors as well.

This makes it a bit more difficult if you'd like to create a library that supports multiple DI frameworks, many of which have (or at least allow you to configure) a requirement that injectable classes have at least one constructor annotated with @Inject.

So, I guess there are a few options here:

  1. Treat @Inject differently from @Autowired when autowiring beans
  2. Change the semantics of @Autowired to require zero or more arguments like @Inject (I'm not sure why this would be a bad thing).
  3. Provide some other mechanism for allowing zero-argument constructors

I'm not that familiar with Spring so perhaps one of these things is already possible. But it didn't seem evident to me looking at the code.


Affects: 4.3.4, 5.0 M3

Reference URL: https://github.com/spring-projects/spring-framework/blob/v5.0.0.M3/spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java#L149

Issue Links:

  • #16883 Make @Autowired optional on a single constructor of a class decorated with @Component
  • #18050 Detect @Autowired constructors for configuration classes

Referenced from: commits 8b5ee4e, 934fffe

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Dec 12, 2016

Juergen Hoeller commented

I don't consider zero-arg @Inject constructors as practically useful and would have preferred if JSR-330 said "one or more arguments" there... That said, we can certainly leniently accept such constructors even for @Autowired. Since we'd simply accept a case that we rejected before, we could also sneak this into 4.3.5 still.

Could you elaborate on your experience with other DI frameworks where there has to be at least one @Inject annotated constructor? What if you're relying on a non-declared default constructor? Or are we talking about classpath scanning there, identifying components by the presence of any @Inject annotation?

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Dec 12, 2016

Greg Methvin commented

Dagger requires you to add a default constructor with @Inject explicitly, assuming there are no fields annotated with @Inject. The rationale is explained very well in this stackoverflow answer: http://stackoverflow.com/a/18344610.

Guice also has an option to require @Inject on constructors: https://google.github.io/guice/api-docs/4.1/javadoc/com/google/inject/Binder.html#requireAtInjectOnConstructors--.

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Dec 12, 2016

Juergen Hoeller commented

Alright, we'll align with that then and leniently accept annotated no-arg constructors as of 4.3.5!

@spring-projects-issues
Copy link
Collaborator Author

@spring-projects-issues spring-projects-issues commented Dec 12, 2016

Greg Methvin commented

Awesome. Thanks for the quick resolution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
2 participants
You can’t perform that action at this time.