码迷,mamicode.com
首页 > Web开发 > 详细

Webx3启动流程

时间:2016-12-05 22:33:44      阅读:301      评论:0      收藏:0      [点我收藏+]

标签:cas   pad   this   proxy   caller   event   应用   手工   ext   

调试petstore-web在debug configurations面板的source tab页中添加项目所依赖的源代码包spring-web-3.2.7.RELEASE-sources.jar&spring-context-3.2.10.RELEASE-sources.jar&citrus-webx-all-3.2.2-sources.jar

 

初始配置:

         引入webx3需要在web.xml文件中,引入以下监听

  日志系统初始化

    <listener><listener-class>com.alibaba.citrus.logconfig.LogConfiguratorListener</listener-class></listener>

  Webx3框架初始化装载/WEB-INF/webx.xml, /WEB-INF/webx-*.xml

    <listener><listener-class>com.alibaba.citrus.webx.context.WebxContextLoaderListener</listener-class></listener>

  请求日志上下文设置

    <filter-class>com.alibaba.citrus.webx.servlet.SetLoggingContextFilter</filter-class></filter>

  请求拦截

    <filter-class>com.alibaba.citrus.webx.servlet.WebxFrameworkFilter</filter-class></filter>

 

入口WebxContextLoaderListener

 技术分享

WebxContextLoaderListener继承自spring的ContextLoaderListener。启动的入口方法为父类的createContextLoader,该方法是创建并初始化contextLoader对象使之成为整个应用的上下文装载器,WebxContextLoaderListener并没有复写父类的这个方法,而是复写了createContextLoader方法,设置WebxComponentsLoader为contextLoader。

 

WebxComponentsLoader

 技术分享

WebxComponentsLoader继承自ContextLoader。覆盖了其中的几个方法,如:initWebApplicationContext,determineContextClass,customizeContext,toString方法。其中比较重要的是determineContextClass和customizeContext。

determineContextClass

determineContextClass这个方法是定义WebApplicationContext的实现类为WebxComponentsContext。父类ContextLoader默认的处理是从所在目录下的ContextLoader.properties中读取如下配置信息。WebxComponentsLoader通过WebxComponentsContext这个类来处理配置文件。

customizeContext

customizeContext方法主要就是设置WebxComponentsContext的loader为WebxComponentsLoader,这样在执行finishRefresh方法的时候会调用WebxComponentsContext的finishRefresh方法,然后该方法会去调用loader的postProcessBeanFactory方法。

WebxComponentsLoader的postProcessBeanFactory方法是在创建beanFactory之初被调用的,它往beanFactory中创建一个bean,对应的class为WebxComponentsCreator,这个类继承自BeanFactoryPostProcessor,而且它的order设置的顺序最末,所以会在PropertyPlaceholderConfigurer执行之后执行。

createWebApplicationContext

ContextLoader的createWebApplicationContext方法里, determineContextClass就是调用WebxComponentsLoader中对应的方法,把ApplicationContext设置为WebxComponentsContext。

 

WebxComponentsContext

 技术分享

WebxComponentsContext的refresh方法是定义在org.springframework.context.support.AbstractApplicationContext.refresh()中的,代码如下

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;

              }

         }

     }

(1)obtainFreshBeanFactory方法。其中的refreshBeanFactory方法代码如下, createBeanFactory方法在Webx3的XmlWebApplicationContext中覆盖过,创建了一个InheritableListableBeanFactory类型的对象,作为bean factory,这是WEBX3对spring进行扩展的一个bean factory。

protected final void refreshBeanFactory() throws BeansException {

     if (hasBeanFactory()) {

         destroyBeans();

         closeBeanFactory();

     }

     try {

         DefaultListableBeanFactory beanFactory = createBeanFactory();

         customizeBeanFactory(beanFactory);

         loadBeanDefinitions(beanFactory);

         synchronized (this.beanFactoryMonitor) {

              this.beanFactory = beanFactory;

         }

     }catch (IOException ex) {

         throw new ApplicationContextException("I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);

     }

}

InheritableListableBeanFactory从这个类的注释可以看出它的的两点重要功能:

1) 子context可继承parent,并能共享父context中的配置和资源;

2) 子context不能覆盖父context中已有的resolvableDependencies对象。否则, WebApplicationContext会自动注册非singleton的request对象 ,使得子context不能取得父context中注册的singleton proxy。通过这个类的处理,可以将request这类的对象注入到Module之中,实际上注入到Module中的是一个代理,对象的实际内容是在运行期从当前线程之中取得实际对象并填充的。

customizeBeanFactory完成annotation注册。通过对allowBeanDefinitionOverriding,allowCircularReferences属性的设置,控制bean fanctory中的bean能否被重写和循环引用。

loadBeanDefinitions方法用于装载应用中的beans。方法中定义XmlBeanDefinitionReader并设置如何去解析xml文档,然后先调用initBeanDefinitionReader方法,其中会调用 springext的XmlWebApplicationContext类, 通过initBeanDefinitionReader这个方法,处理相应的配置扩展点。最后调用loadBeanDefinitions解析xml文档,通过读取/WEB-INF/webx-*.xml和/WEB-INF/webx.xml,获知要装载的bean,然后在AbstractBeanDefinitionParser的parse方法中会调用registerBeanDefinition将bean信息注册到BeanFactory的beanDefinitionMap中去,但并没有完成初始化的操作,初始化这一步在后续进行。

(2)postProcessBeanFactory方法是初始化过程中很重要的一个步骤。该方法最终会调用WebxComponentsLoader的postProcessBeanFactory方法,手工注册WebxComponentsCreator类到BeanFactory中,用以保证初始化的顺序。在webx3中,因为components的初始化依赖于WebxConfiguration,而WebxConfiguration实例的创建使用了PropertyPlaceholderConfigure,因此这些对象要按照一定的顺序创建。首先初始化PropertyPlaceholderConfigure,然后WebxComponentsCreator,最后是其他的BeanFactoryPostProcessors。

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {

    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);

}

(3)invokeBeanFactoryPostProcessors方法分为3步执行。

第一步是执行实现了BeanFactoryPostProcessor接口的类,这些类都是通过addBeanFactoryPostProcessor方法添加到ApplicationContext中去的(PropertyPlaceholderConfigurer);

第二步是按照优先级去执行实现了BeanFactoryPostProcessor以及PriorityOrdered接口的bean(WebxComponentsCreator);

第三步是按照优先级去执行实现了BeanFactoryPostProcessor以及Ordered接口的bean(RequestContextBeanFactoryPostProcessor);

最后是执行仅实现了BeanFactoryPostProcessor接口的bean。

(4)registerBeanPostProcessors方法。注册实现了BeanPostProcessor接口的类,顺序和BeanFactoryPostProcessor类似。

(5)finishBeanFactoryInitialization方法。通过getBean方法去实现bean的初始化。

(6)finishRefresh基于前面创建出来的components创建出其他的子component。

public void finishRefresh() {

    components.getWebxRootController().onFinishedProcessContext();

    for (WebxComponent component : components) {

        logInBothServletAndLoggingSystem("Initializing Spring sub WebApplicationContext: " + component.getName());

        WebxComponentContext wcc = (WebxComponentContext)component.getApplicationContext();

        WebxController controller = component.getWebxController();

        wcc.refresh();

        controller.onFinishedProcessContext();

    }

    logInBothServletAndLoggingSystem("WebxComponents: initialization completed");

}

启动完成。

 

类图如下:

技术分享

 

Webx3启动流程

标签:cas   pad   this   proxy   caller   event   应用   手工   ext   

原文地址:http://www.cnblogs.com/kevinchang/p/6135428.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!