首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

Webx3 初始化进程学习

2012-10-29 
Webx3 初始化过程学习这两天利用空余时间学习了webx3.0,基于spring mvc开发的一款mvc;由于对webx2.0以及sp

Webx3 初始化过程学习

这两天利用空余时间学习了webx3.0,基于spring mvc开发的一款mvc;由于对webx2.0以及spring mvc没有进行过深入的研究,在学习webx3.0的时候,肯定会出现理解上的偏差甚至错误,希望大家积极提出,有问题才是进步的动力;以前很少写文章,文笔不好,还请大家见谅,:)!无废话,开始:

Web.xml,tomcat加载war包开始:

<!-- 装载/WEB-INF/webx.xml, /WEB-INF/webx-*.xml --> <listener>   <listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class></listener>
?

其中WebxContextLoaderListener 信息如下:

?

import org.springframework.web.context.ContextLoader;import org.springframework.web.context.ContextLoaderListener;public class WebxContextLoaderListener extends ContextLoaderListener {……
?

WebxContextLoaderListener继承了spring mvc的监听类:ContextLoaderListener;

Webx3 初始化进程学习

Webx3 初始化进程学习

可想而知,容器启动时,将调用: contextInitialized(ServletContextEvent event)? 该方法,如下:

public void contextInitialized(ServletContextEvent event) {                //1.初始化加载类this.contextLoader = createContextLoader();               //2.出示话web上下文this.contextLoader.initWebApplicationContext(event.getServletContext());}

?

由于WebxContextLoaderListener覆盖了createContextLoader()方法,

 @Override    protected final ContextLoader createContextLoader() {        return new WebxComponentsLoader() {            @Override            protected Class<?> getDefaultContextClass() {                Class<?> defaultContextClass = WebxContextLoaderListener.this.getDefaultContextClass();                if (defaultContextClass == null) {                    defaultContextClass = super.getDefaultContextClass();                }                return defaultContextClass;            }        };    }
?

contextLoader已经是这个了:WebxComponentsLoader 重点关注这个类,

?

public class WebxComponentsLoader extends ContextLoader

?Webx3 初始化进程学习

将负责加载webx中的componet组件,还继承了spring mvc的加载类 ContextLoader,


?所以initWebApplicationContext 就在子类WebxComponentsLoader中执行了:

?

 @Override    public WebApplicationContext initWebApplicationContext(ServletContext servletContext) throws IllegalStateException,            BeansException {        this.servletContext = servletContext;        init();        //开始spring mvc加载…                return super.initWebApplicationContext(servletContext);    }

?经过自己的init后

? super.initWebApplicationContext(servletContext);

? 又回到父类里面去了:

?

public WebApplicationContext initWebApplicationContext(ServletContext servletContext)throws IllegalStateException, BeansException {                  //.....先忽略long startTime = System.currentTimeMillis();try {// Determine parent for root web application context, if any.                        //1.先找parent,一般是空的吧ApplicationContext parent = loadParentContext(servletContext);// Store context in local instance variable, to guarantee that// it is available on ServletContext shutdown.                        //2.创建this.context = createWebApplicationContext(servletContext, parent);                        //3.设为rootservletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context);currentContextPerThread.put(Thread.currentThread().getContextClassLoader(), this.context);//再忽略...return this.context;}catch (RuntimeException ex) {logger.error("Context initialization failed", ex);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex);throw ex;}catch (Error err) {logger.error("Context initialization failed", err);servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err);throw err;}}

?createWebApplicationContext方法主要包括下面4步:

?1.找到上下文类

Class contextClass = determineContextClass(servletContext);

?定位上下文class,这个class可配置;这个方法被WebxContextLoaderListener覆盖,最后返回的class:

return WebxComponentsContext.class;

第二个重要的类出现:WebxComponentsContext
WebxComponentsContext

继承

WebxApplicationContext(webx重写)

继承

XmlWebApplicationContext(spring原生)

Webx3 初始化进程学习

?

2.实例化上下文类

ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);wac.setParent(parent);wac.setServletContext(servletContext);wac.setConfigLocation(servletContext.getInitParameter(CONFIG_LOCATION_PARAM));

?

3.可以自定义操作上下文

customizeContext(servletContext, wac);//被子类覆盖

?此方法也被WebxContextLoaderListener覆盖:

protected void customizeContext(ServletContext servletContext, ConfigurableWebApplicationContext componentsContext) {     this.componentsContext = componentsContext;     if (componentsContext instanceof WebxComponentsContext) {// componentsContext就是上面实例化的上下文,铁定是WebxComponentsContext类               ((WebxComponentsContext) componentsContext).setLoader(this);//为load webx组件配置文件而准备     }}
?

4.初始化IOC容器

wac.refresh();

?
看到熟悉的refush方法了,ConfigurableWebApplicationContext是没有refush方法,AbstractApplicationContext这个类有refush方法:

public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// Prepare this context for refreshing.prepareRefresh();// Tell the subclass to refresh the internal bean factory.ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// Prepare the bean factory for use in this context.prepareBeanFactory(beanFactory);try {// Allows post-processing of the bean factory in context subclasses.postProcessBeanFactory(beanFactory);                                //被覆盖,重点关注                               ?// Invoke factory processors registered as beans in the context.invokeBeanFactoryPostProcessors(beanFactory);// Register bean processors that intercept bean creation.registerBeanPostProcessors(beanFactory);// Initialize message source for this context.initMessageSource();// Initialize event multicaster for this context.initApplicationEventMulticaster();// Initialize other special beans in specific context subclasses.onRefresh();// Check for listener beans and register them.registerListeners();// Instantiate all remaining (non-lazy-init) singletons.finishBeanFactoryInitialization(beanFactory);// Last step: publish corresponding event.finishRefresh();                                //被覆盖,重点关注                        }catch (BeansException ex) {// Destroy already created singletons to avoid dangling resources.beanFactory.destroySingletons();// Reset 'active' flag.cancelRefresh(ex);// Propagate exception to caller.throw ex;}}}
?

postProcessBeanFactory(beanFactory);有覆盖吗?有!

实例化前,webx覆盖了此方法来,进行把webx组件实例放入spring中,怎么放?哪里执行?

((WebxComponentsContext) componentsContext).setLoader(this);

?这里看出是WebxComponentsLoader来进行这个工作:

/**     * 在创建beanFactory之初被调用。     *      * @param webxComponentsContext     */    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {        // 由于初始化components依赖于webxConfiguration,而webxConfiguration可能需要由PropertyPlaceholderConfigurer来处理,        // 此外,其它有一些BeanFactoryPostProcessors会用到components,        // 因此components必须在PropertyPlaceholderConfigurer之后初始化,并在其它BeanFactoryPostProcessors之前初始化。        //        // 下面创建的WebxComponentsCreator辅助类就是用来确保这个初始化顺序:        // 1. PriorityOrdered - PropertyPlaceholderConfigurer        // 2. Ordered - WebxComponentsCreator        // 3. 普通 - 其它BeanFactoryPostProcessors        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(WebxComponentsCreator.class);        builder.addConstructorArgValue(this);        BeanDefinition componentsCreator = builder.getBeanDefinition();        componentsCreator.setAutowireCandidate(false);        BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;        String name = SpringExtUtil.generateBeanName(WebxComponentsCreator.class.getName(), registry);        registry.registerBeanDefinition(name, componentsCreator);    }
?

一个内部类,WebxComponentsCreator辅助类就是用来确保初始化顺序,见上面:

 public static class WebxComponentsCreator implements BeanFactoryPostProcessor, Ordered {        private final WebxComponentsLoader loader;        public WebxComponentsCreator(WebxComponentsLoader loader) {            this.loader = assertNotNull(loader, "WebxComponentsLoader");        }        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {            if (loader.components == null) {                WebxComponentsImpl components = loader.createComponents(loader.getParentConfiguration(), beanFactory);                AbstractApplicationContext wcc = (AbstractApplicationContext) components.getParentApplicationContext();                wcc.addApplicationListener(new SourceFilteringListener(wcc, components));                loader.components = components;            }        }        public int getOrder() {            return Ordered.LOWEST_PRECEDENCE;        }    }

?初始化components:

 /**     * 初始化components。     */    private WebxComponentsImpl createComponents(WebxConfiguration parentConfiguration,                                                ConfigurableListableBeanFactory beanFactory) {                //1.取得一组关于components的配置,也就是component的配置文件,ComponentsConfigImpl中        ComponentsConfig componentsConfig = getComponentsConfig(parentConfiguration);                // 2.假如isAutoDiscoverComponents==true,试图自动发现components         Map<String, String> componentNamesAndLocations = findComponents(componentsConfig, getServletContext());        // 3.取得特别指定的components        Map<String, ComponentConfig> specifiedComponents = componentsConfig.getComponents();        // 4.实际要初始化的comonents,为上述两种来源的并集        Set<String> componentNames = createTreeSet();        componentNames.addAll(componentNamesAndLocations.keySet());        componentNames.addAll(specifiedComponents.keySet());        // 5.创建root controller        WebxRootController rootController = componentsConfig.getRootController();        if (rootController == null) {            rootController = (WebxRootController) BeanUtils.instantiateClass(componentsConfig.getRootControllerClass());        }        // 6.创建并将components对象置入resolvable dependencies,以便注入到需要的bean中        WebxComponentsImpl components = new WebxComponentsImpl(componentsContext, componentsConfig                .getDefaultComponent(), rootController, parentConfiguration);        beanFactory.registerResolvableDependency(WebxComponents.class, components);        // 7.初始化每个component        for (String componentName : componentNames) {            ComponentConfig componentConfig = specifiedComponents.get(componentName);            String componentPath = null;            WebxController controller = null;            if (componentConfig != null) {                componentPath = componentConfig.getPath();                controller = componentConfig.getController();            }            if (controller == null) {                controller = (WebxController) BeanUtils.instantiateClass(componentsConfig.getDefaultControllerClass());            }            WebxComponentImpl component = new WebxComponentImpl(components, componentName, componentPath, componentName                    .equals(componentsConfig.getDefaultComponent()), controller, getWebxConfigurationName());            components.addComponent(component);            prepareComponent(component, componentNamesAndLocations.get(componentName));        }        return components;    }

?怎么找到components,只要找到对应配置项即可

public String getComponentConfigurationLocationPattern() {            return componentConfigurationLocationPattern == null ? "/WEB-INF/webx-*.xml"                    : componentConfigurationLocationPattern;        }//找到了配置文件,接下去要解析了,里面实现比较啰嗦,@#¥#@¥@#¥一大堆,返回
?

未完待续......

?

学习了webx3.0和spring mvc如何结果工作,对于定制web mvc有帮助!

?

?

热点排行
Bad Request.