Webx3启动流程

调试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");

}

启动完成。

类图如下:

时间: 2024-10-19 02:11:56

Webx3启动流程的相关文章

#24 centos6(RHEL)系列操作系统的启动流程、与命令chkconfig、grub的使用

所有由rc脚本关闭或启动的链接文件的原文件都存在于/etc/rc.d/init.d,系统为了方便使用,为此目录创建了链接/etc/init.d 所有/etc/inid.d(/etc/rc.d/init.d)目录中的脚本执行方式: # /etc/init.d/srv_script {start|stop|restart|status} # service srv_script {start|stop|restart|status} chkconfig命令: chkconfig - updates

#23 centos5(RHEL)系列操作系统的启动流程、与命令mkinitrd、dracut的使用

centos(RHEL)系列操作系统的启动流程:Intel x86兼容架构: Linux的系统组成:内核 + 应用程序  GUN/Linux:单纯的指Linux内核: 从硬盘存储和启动操作系统的角度: Linux的系统组成:内核 + 根文件系统(rootfs) 内核功能:进程管理,文件系统管理,内存管理,网络协议,驱动程序,安全功能,... Linux系统的系统运行环境可以分为两部分: 内和空间:内核代码(系统调用) 就是内核进程占用的CPU和内存资源的总和: 用户空间:应用程序(进程或线程)

CentOS 6开机启动流程实验篇

CentOS 6开机启动流程实验篇 centos 系统的启动流程 grub 破坏Linux的核心文件再修复体验系统启动流程 CentOS 6开机启动的具体详情请参见理论篇! 了解了系统启动的基本流程,以下我们通过"破坏式实验",即破坏系统启动过程中的一些关键环节,使系统无法启动,然后我们再通过修复这些文件使得系统正常重启,进而体验Linux系统的启动流程,这些关键环节包括破坏grub三个stage(stage1.stage1-5.stage2) 中的任何一个阶段,甚至是整个grub;

u-boot启动流程分析(2)_板级(board)部分

转自:http://www.wowotech.net/u-boot/boot_flow_2.html 目录: 1. 前言 2. Generic Board 3. _main 4. global data介绍以及背后的思考 5. 前置的板级初始化操作 6. u-boot的relocation 7. 后置的板级初始化操作 1. 前言 书接上文(u-boot启动流程分析(1)_平台相关部分),本文介绍u-boot启动流程中和具体版型(board)有关的部分,也即board_init_f/board_i

CentOS开机启动流程简介

我们都知道按下电脑电源键后,屏幕上会一闪而过很多信息,然后显示登录界面,然后输入用户名,密码就可以畅享网络世界了.那么这中间到底发生了什么呢,今天就让我们来简单探讨一下CentOS的简易版开机启动流程吧. 第一阶段:通电自检过程 我们都知道电脑所有数据指令都是在内存上才能被cpu处理的吧,我们还知道内存在断电后其上面的所有数据都会丢失吧,那么开机的时候内存应该是没有东西的吧,那上面都不能干了,更别说启动一个操作系统了,其实啊,我们内存并不只是我们常见的那个内存卡,很多硬件都会映射一段内存到cpu

Cocos2d-x3.3RC0的Android编译Activity启动流程分析

本文将从引擎源代码Jni分析Cocos2d-x3.3RC0的Android Activity的启动流程,以下是具体分析. 1.引擎源代码Jni.部分Java层和C++层代码分析 watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveXV4aWt1b18x/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" > watermark/2/text/aHR0cDov

centos启动流程[转]

启动流程概览 在硬件驱动成功后,Kernel 会主动呼叫 init 程序,而 init 会取得 run-level 资讯: init 运行 /etc/rc.d/rc.sysinit 文件来准备软件运行的作业环境 (如网络.时区等): init 运行 run-level 的各个服务之启动 (script 方式): init 运行 /etc/rc.d/rc.local 文件: init 运行终端机模拟程序 mingetty 来启动 login 程序,最后就等待使用者登陆啦:    init,/etc

System进程的启动流程第二部分

继System进程的启动流程第一部分,我们接着分析com.android.server.SystemServer的main函数.如下: public class SystemServer { ...... native public static void init1(String[] args); ...... public static void main(String[] args) { ...... init1(args); ...... } public static final vo

UI开发----基础视图和程序启动流程(delegate)

//  Create by 郭仔  2015年04月13日22:10:23 今天介绍的基础视图包括:UITextField.UIButton 一.定义UITextField: 创建UITextField与创建UILabel的步骤很相似.? 1.开辟空间并初始化(如果本类有初始化?方法,使?用?自?己的;否则 使?用?父类的).? 2.设置?文本显?示.输?入相关的属性? 3.添加到?父视图上,?用以显?示? 4.释放 UITextField * textField = [[UITextField