beandefinition 是spring中对对象关系,对象创建等一系列的定义模型,其本质其实是一个Map集合,其类图我们可以看一下:
在我们创建初始化容器时,也就是bean工厂时,会根据这个工厂创建相应的 BeanDefinitionReader 对象,这个reader对象是一个资源解析器,这个解析的过程是复杂的在我们后边的解析中会具体来看各自的实现
4. ResourceLoader所属包 org.springframework.core.io.ResourceLoader ,这是spring用来进行统一资源加载的顶级接口,里面定义行为,实现让具体的子类实现,类图我们可以看一下
类图中展示的是 ResourceLoader 的核心实现, 在 spring 中容器也有实现该接口,关于统一资源加载的运转后期会专门说明 5. Resource
所属包 org.springframework.core.io.Resource , 该类是 spring 中资源加载的策略实现顶层接口,该类的每个实现类都是对某一种资源的访问策略,类图:
我们在springMvc中很熟悉一个核心控制器 DispatcherServlet , 这个类做了一个集中分发和 web 容器初始的功能,首先我们来看一下类图
我们可以看到 DispatcherServlet 继承了 HttpServlet ,我们熟悉 HttpServlet 是属于Servlet的 ,那么它必然有个 init() 的初始化方法,我们通过查看,可以看到在 HttpServletBean 中重写了 init 方法
/** * 重写了init方法,对ServletContext初始化 * Map config parameters onto bean properties of this servlet, and * invoke subclass initialization. * @throws ServletException if bean properties are invalid (or required * properties are missing), or if subclass initialization fails. */ @Override public final void init() throws ServletException { // Set bean properties from init parameters. //读取初始化参数 如web.xml中 init-param PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties); if (!pvs.isEmpty()) { try { BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext()); bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment())); initBeanWrapper(bw); bw.setPropertyValues(pvs, true); } catch (BeansException ex) { if (logger.isErrorEnabled()) { logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex); } throw ex; } } // Let subclasses do whatever initialization they like. //初始化容器 是让子类FrameworkServlet具体实现的 initServletBean(); }我们可以看到, init 方法中具体的容器实例方法 FrameworkServlet 来实现的,我们跟进去看一下 initialServletBean 的具体实现
/** * Overridden method of {@link HttpServletBean}, invoked after any bean properties * have been set. Creates this servlet's WebApplicationContext. * 构建 web 上下文容器 */ @Override protected final void initServletBean() throws ServletException { getServletContext().log("Initializing Spring " + getClass().getSimpleName() + " '" + getServletName() + "'"); if (logger.isInfoEnabled()) { logger.info("Initializing Servlet '" + getServletName() + "'"); } long startTime = System.currentTimeMillis(); try { //容器初始化 this.webApplicationContext = initWebApplicationContext(); initFrameworkServlet(); } catch (ServletException | RuntimeException ex) { logger.error("Context initialization failed", ex); throw ex; } if (logger.isDebugEnabled()) { String value = this.enableLoggingRequestDetails ? "shown which may lead to unsafe logging of potentially sensitive data" : "masked to prevent unsafe logging of potentially sensitive data"; logger.debug("enableLoggingRequestDetails='" + this.enableLoggingRequestDetails + "': request parameters and headers will be " + value); } if (logger.isInfoEnabled()) { logger.info("Completed initialization in " + (System.currentTimeMillis() - startTime) + " ms"); } }