前言 在springMVC(12) ContextLoaderListener 中我们有遇到一个方法configureAndRefreshWebApplicationContext,这个方法就是用来做spring IOC容器初始化操作的。
configureAndRefreshWebApplicationContext方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 protected void configureAndRefreshWebApplicationContext (ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null ) { wac.setId(idParam); } else { wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } wac.setServletContext(sc); String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocationParam != null ) { wac.setConfigLocation(configLocationParam); } ConfigurableEnvironment env = wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null ); } customizeContext(sc, wac); wac.refresh(); }
determineContextInitializerClasses方法 由于customizeContext中调用了determineContextInitializerClasses,于是我们此处先看determineContextInitializerClasses方法的源码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 protected List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> determineContextInitializerClasses (ServletContext servletContext) { List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> classes = new ArrayList <Class<ApplicationContextInitializer<ConfigurableApplicationContext>>>(); String globalClassNames = servletContext.getInitParameter(GLOBAL_INITIALIZER_CLASSES_PARAM); if (globalClassNames != null ) { for (String className : StringUtils.tokenizeToStringArray(globalClassNames, INIT_PARAM_DELIMITERS)) { classes.add(loadInitializerClass(className)); } } String localClassNames = servletContext.getInitParameter(CONTEXT_INITIALIZER_CLASSES_PARAM); if (localClassNames != null ) { for (String className : StringUtils.tokenizeToStringArray(localClassNames, INIT_PARAM_DELIMITERS)) { classes.add(loadInitializerClass(className)); } } return classes; }
这个方法主要是用来获取初始化类的,这些类均继承这样一个接口,
1 2 3 public interface ApplicationContextInitializer <C extends ConfigurableApplicationContext > { void initialize (C applicationContext) ; }
我们可以通过继承这个接口来进行写自己的初始化类,并且进行相应配置,关于这部分的作用可以参考如下文章http://blog.csdn.net/qingxiutianya/article/details/51735741
customizeContext方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 protected void customizeContext (ServletContext sc, ConfigurableWebApplicationContext wac) { List<Class<ApplicationContextInitializer<ConfigurableApplicationContext>>> initializerClasses = determineContextInitializerClasses(sc); if (initializerClasses.isEmpty()) { return ; } ArrayList<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerInstances = new ArrayList <ApplicationContextInitializer<ConfigurableApplicationContext>>(); for (Class<ApplicationContextInitializer<ConfigurableApplicationContext>> initializerClass : initializerClasses) { Class<?> initializerContextClass = GenericTypeResolver.resolveTypeArgument(initializerClass, ApplicationContextInitializer.class); if (initializerContextClass != null ) { Assert.isAssignable(initializerContextClass, wac.getClass(), String.format( "Could not add context initializer [%s] since its generic parameter [%s] " + "is not assignable from the type of application context used by this " + "context loader [%s]: " , initializerClass.getName(), initializerContextClass.getName(), wac.getClass().getName())); } initializerInstances.add(BeanUtils.instantiateClass(initializerClass)); } AnnotationAwareOrderComparator.sort(initializerInstances); for (ApplicationContextInitializer<ConfigurableApplicationContext> initializer : initializerInstances) { initializer.initialize(wac); } }
如果清楚了initializerClasses是个怎么的东西之后,我们可以很清楚地知道这个方法的作用,就是执行自己定制的初始化类。
refresh方法 这个方法才是最后真正用来初始化spring IoC容器的。
这个方法是WebApplicationContext的。由于默认的WebApplicationContext是XmlWebApplicationContext,我们就接着来看XmlWebApplicationContext中实现。感觉可能有点长,另开一章吧。spring(2) web应用中spring IOC容器初始化(2)