DispatcherServlet的静态初始化
/** * Name of the class path resource (relative to the DispatcherServlet class) * that defines DispatcherServlet's default strategy names. */ private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";private static final Properties defaultStrategies; static { // Load default strategy implementations from properties file. // This is currently strictly internal and not meant to be customized // by application developers. try { ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class); defaultStrategies = PropertiesLoaderUtils.loadProperties(resource); } catch (IOException ex) { throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage()); } }
配置文件加载
/** * Load properties from the given resource (in ISO-8859-1 encoding). * @param resource the resource to load from * @return the populated Properties instance * @throws IOException if loading failed * @see #fillProperties(java.util.Properties, Resource) */ public static Properties loadProperties(Resource resource) throws IOException { Properties props = new Properties(); fillProperties(props, resource); return props; }
属性填充:
/** * Fill the given properties from the given resource (in ISO-8859-1 encoding). * @param props the Properties instance to fill * @param resource the resource to load from * @throws IOException if loading failed */ public static void fillProperties(Properties props, Resource resource) throws IOException { InputStream is = resource.getInputStream(); try { String filename = resource.getFilename(); if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) { props.loadFromXML(is); } else { props.load(is); } } finally { is.close(); } }
我们从这个可以得到什么呢?
我们可以直接拿过来作为读取属性文件的工具类。
DispatcherServlet的策略初始化
初始化策略代码:
/** * Initialize the strategy objects that this servlet uses. * <p>May be overridden in subclasses in order to initialize further strategy objects. */ protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }
我们再看一个这个方法结构图:
从上面的图中我们可以看出它们都共同使用一个方法:
/** * Create a List of default strategy objects for the given strategy interface. * <p>The default implementation uses the "DispatcherServlet.properties" file (in the same * package as the DispatcherServlet class) to determine the class names. It instantiates * the strategy objects through the context's BeanFactory. * @param context the current WebApplicationContext * @param strategyInterface the strategy interface * @return the List of corresponding strategy objects */ @SuppressWarnings("unchecked") protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) { String key = strategyInterface.getName(); String value = defaultStrategies.getProperty(key); if (value != null) { String[] classNames = StringUtils.commaDelimitedListToStringArray(value); List<T> strategies = new ArrayList<T>(classNames.length); for (String className : classNames) { try { Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader()); Object strategy = createDefaultStrategy(context, clazz); strategies.add((T) strategy); } catch (ClassNotFoundException ex) { throw new BeanInitializationException( "Could not find DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]", ex); } catch (LinkageError err) { throw new BeanInitializationException( "Error loading DispatcherServlet's default strategy class [" + className + "] for interface [" + key + "]: problem with class file or dependent class", err); } } return strategies; } else { return new LinkedList<T>(); } }
StringUtils 和ClassUtils 可以一个丰富的代码库哦。
更进一步 我们可以从spring的源码库查找所有的*utils.java类,发现一个巨大的代码库,从中学习和重新利用这类工具类库,我们可以完善自己的代码库,加快开发效率。