1

I have a Spring MVC @Controller named MyController. I can inject the Spring Environment in its constructor:

public MyController(Environment environment) {
  …
}

But if I try to inject the same Environment into a request handler, it fails:

@GetMapping
public String getFoo(Environment environment)

The error message is:

No primary or single unique constructor found for interface org.springframework.core.env.Environment

I note that I can inject the HTTP servlet request in the handler with no problem:

public String getFoo(HttpServletRequest request)

Why can I inject Environment in the controller constructor, but not in a handler method?

Where in the documentation can I go to get a list of things that can only be injected in one place or the other?

Garret Wilson
  • 18,219
  • 30
  • 144
  • 272
  • Because in constructor it is (implicitly) `@Autowired` ..and in controller (method) it complies (only!) with ["(mvc) method arguments"](https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#mvc-ann-arguments) (where `Environment` would be interpreted as `@RequestParam/ModelAttribute`...last row ;) – xerx593 Mar 27 '23 at 20:43
  • HttpServletRequest is special (2nd row;) – xerx593 Mar 27 '23 at 20:46
  • But the key point: constructors of a controller/bean/component/... *significantly differ* from "annotated controller methods" – xerx593 Mar 27 '23 at 20:49
  • If you need to access `Environment` within your controllers, you can use the one (and normally only) "from constructor".. – xerx593 Mar 27 '23 at 20:52
  • 1
    I try to make it an answer!:) – xerx593 Mar 27 '23 at 20:55

1 Answers1

0

"Annotated Controllers"

  • "Handler Methods"
    • "Method Arguments" are very specific parts of spring-web (/-webflux), handled and populated by (very) specific "converters, filters, handlers, adapters, (holy etc.)" and (should) conform with the linked (version specific;( documentation.

Whereas "dependency injection", auto-wiring (as Environment) are very general parts (spring-context,-beans,-core) of "spring infrastructure". Best to start: at the top!:)

xerx593
  • 12,237
  • 5
  • 33
  • 64
  • If I understand correctly, you are saying that Spring MVC controller request mapping methods don't technically do full Spring dependency injection auto-wiring; rather they only support a limited number of things they know how to inject, documented at the links you gave. – Garret Wilson Mar 27 '23 at 21:53
  • You got me right, @GarretWilson... Especially the last part (as the doc states). So most correct: "...they only support a limited number of things they know how to inject, documented at the links you gave." – xerx593 Mar 27 '23 at 22:07
  • Well the documentation isn't very clear on the distinction and leaves it to the reader to figure it out. I found one sentence that implies the difference: "`@RequestMapping` handler methods have a flexible signature and can choose from a range of supported controller method arguments and return values." I guess "supported … arguments" implies that handler methods _only_ support the listed arguments, and that otherwise normal autowiring doesn't apply. I think the documentation could have been a bit more explicit. Thanks for pointing me to this list. – Garret Wilson Mar 27 '23 at 23:22
  • This issue came up again in https://stackoverflow.com/q/76039575 . It took me a little while, but then I remembered the answer here, so this answer is serving extra duty. I'll add a bounty to assign to this answer because it's proving so useful. Thanks. – Garret Wilson Apr 17 '23 at 22:30