Spring之动手实现SpringMVC功能

1 简介 SpringMVC大家应该耳熟能详,只要是做Java网站开发的小伙伴,都会使用的框架。SpringMVC以 DispatcherServlet 为核心,负责协调和组织不同组件以完成请求处理并返回响应的工作,实现了MVC模式。接下来我们从 该框架的流程 来整理设计思路,最后自己实现一个mvc框架. 2 SpringMVC运行流程 springmvc的流程如下: API说明 _DispatcherServlet_: Spring提供的前端控制器,所有的请求都有经过它来统一分发。在DispatcherServlet将请求分发给Controller之前,需要借助于Spring提供的HandlerMapping定位到具体的Controller。 HandlerMapping : 完成客户请求到Controller映射,包括拦截器部分内容 Controller : Controller将处理用户请求,调用业务层接口分析,并返回ModelAndView对象给DispatcherServlet前端控制器,ModelAndView中包含了模型(Model)和视图(View) ViewResolver : Spring提供的视图解析器(ViewResolver)在Web应用中查找View对象,会根据当前的视图渲染引擎(JSP FreeMarker Thymeleaf)来渲染视图,返回给前端 流程概述 1 用户发送请求至前端控制器DispatcherServlet 2 DispatcherServlet收到请求调用HandlerMapping处理器映射器 3 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。 4 DispatcherServlet通过HandlerAdapter处理器适配器调用处理器 5 执行处理器(Controller,也叫后端控制器)。 6 Controller执行完成返回ModelAndView 7 HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet 8 DispatcherServlet将ModelAndView传给ViewReslover视图解析器 9 ViewReslover解析后返回具体View 10 DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中) 11 DispatcherServlet响应用户 3 MVC之九大组件 SpringMVC中的Servlet一共有三个层次,分别是HttpServletBean、FrameworkServlet和 DispatcherServlet。 HttpServletBean直接继承自java的HttpServlet,其作用是将Servlet中配置的参数设置到相应的属性; FrameworkServlet初始化了WebApplicationContext,DispatcherServlet初始化了自身的9个组件。 DispatcherServlet初始化方法 protected void onRefresh(ApplicationContext context) { initStrategies(context); } protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); } 具体9个组件介绍如下:

Spring之动手实现IOC功能

1 背景 我们经常在使用Spring生态中的组件,我们在潜移默化的DI和IOC的思想下,来创建和使用Bean对象,使用过 @Component @ComponentScan @Autowired @Bean @Configuration 等等的注解,所以了解Spring容器是如何创建和管理Bean,是我们必需掌握的技能。 下面我们通过手写DI和IOC的方式来加深对Spring的理解。 #2 依赖注入 DI,Dependency Injection,即依赖注入。具体含义表示组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。对象只提供普通的方法让容器去决定依赖关系。 Spring中创建Bean的方式有三种: 通过XML显式配置 通过Java显式配置 (利用 @Configuration @Bean) 隐式进行bean搜索并自动装配 (利用基于@Component 元注解的方式) 通过上面叙述我们知道,创建bean其实大致可以分为两种,一种是基于XML,另一种是基于注解的方式。 2.1 XML方式 user.xml <?xml version="1.0" encoding="UTF-8"?> <beans> <bean id="studentA" class="iockids.xml.Student" scope="singleton"> <property name="age" value="20"/> <property name="name" value="nana"/> <property name="address" value="hangzhou"/> </bean> <bean id="studentB" class="iockids.xml.Student" scope="prototype"> <property name="name" value="nicky"/> <property name="age" value="22"/> <property name="address" value="ningbo"/> </bean> </beans> Student对象 @Data public class Student { private String name; private Integer age; private String address; } /** * 单例对象容器 */ private Map<String, Object> singletonBeanFactory = new ConcurrentHashMap<>(); /** * bean对象的容器 */ private Map<String, Class<?

Spring之Bean加载-解析-生命周期

1 概要 使用Spring框架,我们需要了解Bean的创建加载过程,需要熟悉Bean是如何获取和使用的。 下面我们通过分析下Spring加载XML文件的过程来分析Bean的数据流。 当前调试的Spring 版本是最新的 4.1.0 release 版本 调试代码主入口 ApplicationContext context = new ClassPathXmlApplicationContext("consumer.xml"); System.out.println("Consumer Started"); ConsumerBean bean = context.getBean(ConsumerBean.class); String secretKey = bean.getProperties().getProperty("SecretKey"); System.out.println(secretKey); 2 解析过程 创建 ClassPathXmlApplicationContext对象,会调用refresh()方法 public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. prepareRefresh(); // 获取xml文件的信息,存储在beanFactory对象中 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); .................省略中间代码 // 注册bean信息 invokeBeanFactoryPostProcessors(beanFactory); // 实例化bean finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. finishRefresh(); } 之后会进入AbstractApplicationContext对象,处理如下方法: