Java Spring容器如何引用我们作为参数传递给方法的接口或类类型
我一直在研究spring和SpringMVC框架,我很想知道spring容器如何为我们提供对作为参数传递给方法的任何接口或类类型的引用 例如,当我们在web应用程序中创建Servlet时,它会扩展HttpServlet,因此当我们重写doGet或doPost方法时,web容器会实例化Servlet,并将对HttpServletRequest和HttpServletResponse对象的引用传递给doGet或doPost方法,如下所示:Java Spring容器如何引用我们作为参数传递给方法的接口或类类型,java,spring,spring-mvc,servlets,dependency-injection,Java,Spring,Spring Mvc,Servlets,Dependency Injection,我一直在研究spring和SpringMVC框架,我很想知道spring容器如何为我们提供对作为参数传递给方法的任何接口或类类型的引用 例如,当我们在web应用程序中创建Servlet时,它会扩展HttpServlet,因此当我们重写doGet或doPost方法时,web容器会实例化Servlet,并将对HttpServletRequest和HttpServletResponse对象的引用传递给doGet或doPost方法,如下所示: public class DemoServlet exten
public class DemoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//container gives reference to request and response object
}
}
我想到的问题是,spring容器如何知道它需要实例化什么对象引用,也就是说,当我们的类不重写任何类或接口方法时,它如何扫描这些方法,以便知道它需要提供对该对象的引用。因为这些类或接口类型并没有在应用程序上下文文件中声明为bean。例如:
@Controller
@RequestMapping("/")
public class ContactController {
@RequestMapping(value="savecontact", method=RequestMethod.POST)
public String saveContact(@ModelAttribute("contact") Contact contact, BindingResult errors, HttpServletRequest request, HttpServletResponse response) {
...
}
}
Spring如何提供对BindingResult、HttpServletRequest、HttpServletResponse对象以及我们作为参数传递给方法的任何其他Spring或Servlet类或接口类型的引用?它是否有在应用程序启动时实例化的默认对象列表,或者是否扫描方法?当您使用
@RequestMapping
注释控制器方法时,该方法的参数将成为参数解析过程的主题。接口及其实现是该机制的核心。该接口包含两种方法支持
,以及解析参数
简单地说,所有列出的参数都通过注册到的默认解析程序列表传递(检查getDefaultArgumentResolver
方法),如果解析程序支持该类型,则调用resolveArgument
方法并将实例作为参数注入
对于您声明的四种类型,相应的解析器是
ServletModelAttributeMethodProcessor
ErrorsMethodArgumentResolver
ServletRequestMethodArgumentResolver
ServletResponseMethodArgumentResolver
基于参数解析机制,添加一个将实例化并注入任何自定义类型的实例也很容易,作为主从答案的后续内容
- 方法参数上的@ModelAttribute指示应从模型中检索该参数。如果模型中不存在,
应该首先实例化参数,然后将其添加到模型中。
参数字段一旦出现在模型中,就应该
从具有匹配名称的所有请求参数填充。这
在SpringMVC中称为数据绑定 - spring在何处找到@ModelAttribute方法arg:
- 它可能已经在模型中了
- 由于使用
- 由于同一控制器中的@ModelAttribute方法
- 它可以基于URI模板变量和类型转换器进行检索(下面将详细说明)
- 可以使用其默认构造函数对其进行实例化
- 它可能已经在模型中了
框架内部遵循我们在没有框架的情况下手动执行的所有算法。