Webx3启动过程

Webx3是一个开源框架,开源地址:http://openwebx.org/docs/intro.html

Webx3启动过程

初始配置:

         引入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继承自springContextLoaderListener。启动的入口方法为父类的createContextLoader,该方法是创建并初始化contextLoader对象使之成为整个应用的上下文装载器,WebxContextLoaderListener并没有复写父类的这个方法,而是复写了createContextLoader方法,设置WebxComponentsLoadercontextLoader

 

WebxComponentsLoader

 

WebxComponentsLoader继承自ContextLoader覆盖了其中的几个方法,如:initWebApplicationContextdetermineContextClasscustomizeContexttoString方法。其中比较重要的是determineContextClasscustomizeContext

determineContextClass

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

customizeContext

customizeContext方法主要就是设置WebxComponentsContextloaderWebxComponentsLoader,这样在执行finishRefresh方法的时候会调用WebxComponentsContextpostProcessBeanFactory方法,然后该方法会去调用loaderpostProcessBeanFactory方法。

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

createWebApplicationContext

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

 

WebxComponentsContext

WebxComponentsContextrefresh方法是定义在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;

              }

         }

     }

1obtainFreshBeanFactory方法。其中的refreshBeanFactory方法代码如下, createBeanFactory方法在Webx3XmlWebApplicationContext中覆盖过,创建了一个InheritableListableBeanFactory类型的对象,作为bean factory,这是WEBX3spring进行扩展的一个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会自动注册非singletonrequest对象 ,使得子context不能取得父context中注册的singleton proxy。通过这个类的处理,可以将request这类的对象注入到Module之中,实际上注入到Module中的是一个代理,对象的实际内容是在运行期从当前线程之中取得实际对象并填充的。

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

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

2postProcessBeanFactory方法是初始化过程中很重要的一个步骤。该方法最终会调用WebxComponentsLoaderpostProcessBeanFactory方法,手工注册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);

}

3invokeBeanFactoryPostProcessors方法分为3步执行。

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

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

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

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

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

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

6finishRefresh基于前面创建出来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");

}

启动完成。

 

启动完成后,当发生请求时,执行情况:

 

 

猜你喜欢

转载自angela111.iteye.com/blog/1358741