Spring MVC中构造器可注入Environment,请求处理方法却不行?
Spring MVC注入Environment的问题解答
问题描述
我有一个Spring MVC的@Controller类MyController,能够在其构造器中注入Spring Environment:
public MyController(Environment environment) { … }
但尝试将同一个Environment注入请求处理方法时却失败了:
@GetMapping public String getFoo(Environment environment)
错误信息为:
No primary or single unique constructor found for interface org.springframework.core.env.Environment
我注意到在处理方法中注入HttpServletRequest是没有问题的:
public String getFoo(HttpServletRequest request)
请问为什么Environment可以在控制器构造器中注入,却不能在请求处理方法中注入?在哪里可以查阅到仅能在其中一处注入的对象列表?
原因分析
这两种注入方式的底层逻辑完全不同:
- 构造器注入:属于Spring核心的依赖注入(DI)机制。
Environment是Spring容器管理的顶级单例Bean,所有被Spring容器托管的Bean(包括@Controller)都能通过构造器、字段或Setter方法直接注入这类容器级Bean。 - 请求处理方法参数注入:这是Spring MVC专属的请求参数解析机制,并非通用的依赖注入。Spring MVC只会自动解析填充和当前HTTP请求上下文强绑定的特定类型参数——比如
HttpServletRequest、HttpServletResponse、Model、带@RequestParam注解的参数、@RequestBody标注的实体类等。
Environment不属于请求上下文相关类型,Spring MVC没有为它注册对应的参数解析器。当你把它放在请求方法参数中时,Spring会尝试通过反射实例化它(因为找不到合适的解析器),但Environment是接口,没有可直接实例化的构造器,因此抛出上述错误。
相关对象范围查阅方式
无需寻找“仅能在某一处注入”的列表,只需区分两类注入的适用范围:
- 容器级Bean(支持构造器/字段/Setter注入):所有被Spring容器管理的Bean都属于此类,包括
Environment、ApplicationContext、自定义的Service/Repository等,可通过Spring官方文档的Bean定义部分或项目中的Bean配置确认。 - Spring MVC请求方法支持的参数类型:查看Spring官方文档中关于
@RequestMapping(及衍生注解如@GetMapping)方法参数的章节,里面会列出所有支持自动解析的类型,涵盖请求/响应对象、会话对象、模型对象、各类注解绑定的参数等。
内容的提问来源于stack exchange,提问作者Garret Wilson
相关产品推荐
相关产品推荐

