note2.Webx 2.x初始化之webxLoader

Webx初始化之webxLoader:

上一个note主要记录了webx整体调用过程和步骤:从webxController → RunData构建 → Pipeline调用  → valve逐个调用 → module调用

本note将以webx框架中几个主要的对象初始化来讲解整个webx框架初始化过程

webxLoader是WebxController接口的实现:

对web应用讲:保存了一个web应用中所有的配置(ServletConfig)和上下文(ServletContext)信息。
对webx框架讲:是整个框架的控制器,也是所有Services的构建容器,是框架对象的信息载体和服务提供者。
webxLoader类图关系如下: 

可以看到webxLoader是WebxControllerListener和WebxControllerServlet的全局变量。

WebxLoader的初始化过程:
webxControllerListener:

当web容器启动时,先调用listener的contextInitialized()
1.先试着去应用上下文获取webxLoader的对象引用,启动时肯定获取不到
2.发现无法获取到对应的webxLoader,新建webxLoader对象,初始化webxLoader中的log、servletContext对象,并设置ServletConfig为null。
Note1:虽然目前已经完成了log初始化,但是由于log配置还没有加载,log实际是不可用的
3.配置webxLoader对象。配置主要分为以下几个步骤:
a) 创建资源加载器
    在配置是先创建WebappBootstrapResourceLoaderService对象resourceLoader,用来获取各个配置文件的路径
Note2:这里因为还没配置logger,所以设置loggerReady为false,表示日志系统还没准备好
b) 配置日志系统
    取日志输出根目录路径;试着从web.xml容器获取loggingRoot的值,exodus2应用中配置了相关项,获取日志根目录的位置,loggingRoot值在具体应用中采用autoconfig注入;
    设置日志的几个参数值:loggingRoot(日志记录根目录)、server.host(主机名)、server.addr(主机地址);
    取log4j的配置文件路径:试着去web.xml中获取log4j.configuration值,exodus2中没有配置,所以采用默认路径/WEB-INF/log4j.xml,如果去解开war包,就能在WEB-INF中看到对应的文件;
    根据路径装载log4j的配置路径载入文件:如果配置路径是以.xml结尾,表示采用log4j的xml方式载入,其他的方式采用properties载入;
    设置loggerReady为true表示可以进行日志记录了,和Note2对应,如果把日志级别调整到info,就会发现webx.log日志最开始是"Configured log4j from",接着就是"====================",代码log4j配置就是从这里开始;
c) 获取scheme
    设置schemeName:试着从web.xml容器获取webx.scheme相关配置,exodus2没有配置所以无法获取,设置为默认值"turbine";
    加载schemeClass:采用当classLoader去加载classpath中"META-INF/Services/webx.scheme.turbine"文件,在"jar:file:/home/madding/workspace/olps/exodus2/webx_experiment/deploy/jboss_server/tmp/deploy/tmp1696684320301442655web-exp.war/WEB-INF/lib/toolkit.webx.turbine-2.0.jar!/META-INF/services/webx.scheme.turbine"找到了对应的配置项并加载。目前该配置文件配置了scheme类名为"com.alibaba.turbine.scheme.TurbineScheme"(在初始化services时调用这个类);
Note3:这里的加载方式和log4j找文件的加载方式不同,所以能加载到classpath中的资源
    生成对应的scheme类:用classLoader新建一个实例,scheme对象生成。
Note4.目前webxLoader已经完成了以下几个成员变量的初始化:log、servletContext、scheme
d) 获取servletPaths
    获取servletPahts列表:试着从web.xml容器获取webx.servlet.paths对象,exodus2中没有配置,所以获取不到,返回一个空数组;
    servletPaths对象目前为非null,但是是空数组
e) 获取webx配置文件
    获配webx配置文件路径:试着去web.xml容器中获取"webx.configuration"值,exodus2中没有配置,采用scheme的默认配置值"/WEB-INF/webx.xml";
    获取配置项的URL:exodus2中没有配置"webx.xml",抛出异常并捕获
    新建webx配置类:试着去web.xml文件中查找"webx.configuration.loader.class",exodus2中没配置,采用scheme的默认配置加载类"com.alibaba.webx.configuration.WebxConfigurationLoader",最终配置类采用的是基本配置类新建出来
    获取组件名列表:试着去web.xml容器中获取"webx.components"值,exodus2配置了这个配置项,值为:"home,member,company,offer,misc,ims,product,bizexpress,message,aso,domain,smarket,album",就是exodus2包含的13个web组件,去除空格保存在临时数组中。
    获取每个组件配置信息,举例home组件:
        获取home组建的配置路径:jndi:/localhost/WEB-INF/home/webx.xml
        判断一下当前组件是否在resourceLoader中,如果不在其中,设置组件信息并把这个组件实例放到实例池中,后面会用到这个resourceLoader去获取组件
        加载组件对应的webx.xml文件,保存到componentConfiguration临时对象中
        去除重复对象
    把webx.xml中值以key/value方式不断的组合转存到要返回的配置文件对象中。
Congiguration内容如下:{
services.instances=home,
home.services.ModuleLoaderService.earlyInit=false,
home.services.ModuleLoaderService.module.packages=[com.alibaba.exodus2.web.home.module, com.alibaba.exodus2.web.common.module],
home.services.SecurityMappingService.class=com.alibaba.china.common.webx.service.mapping.SecurityMappingService,
home.services.SecurityMappingService.earlyInit=false,
home.services.VelocityService.class=com.alibaba.service.velocity.DefaultVelocityService,
home.services.VelocityService.earlyInit=true,
home.services.VelocityService.file.resource.loader.path=/templates/home,
home.services.VelocityService.file.resource.loader.cache=true,
home.services.VelocityService.input.encoding=GBK,
home.services.VelocityService.parser.pool.size=20,
home.services.VelocityService.velocimacro.library=[macros.vm,/security/securitymacro.vm],
home.services.VelocityService.eventCartridge.classes=com.alibaba.china.fasttext.security.velocity.SecurityReferenceInsertionEventHandler
}
对比一下对应的webx.xml:
<?xml version="1.0" encoding="GB2312"?>
<configuration>
    <services>
        <!- 装载turbine module的service,例如:screen、action、control等。 ->
        <service name="ModuleLoaderService">
            <property name="module.packages">
                <value>com.alibaba.exodus2.web.home.module</value>
                <value>com.alibaba.exodus2.web.common.module</value>
            </property>
        </service>
        <service name="SecurityMappingService" class="com.alibaba.china.common.webx.service.mapping.SecurityMappingService">
            <property name="unProtectedURLs"/>            
        </service>
        <!- Velocity模板引擎,用来渲染velocity写成的页面模板。需要TemplateService的支持。 ->
        <service name="VelocityService"
            class="com.alibaba.service.velocity.DefaultVelocityService" earlyInit="true">
            <property name="file.resource.loader.path" value="/templates/home"/>
            <property name="file.resource.loader.cache" value="true"/>
            <property name="input.encoding" value="GBK"/>
            <property name="parser.pool.size" value="20"/>
            <property name="velocimacro.library" value="macros.vm"/>
            <property name="velocimacro.library" value="/security/securitymacro.vm" />
            <property name="eventCartridge.classes" value="com.alibaba.china.fasttext.security.velocity.SecurityReferenceInsertionEventHandler" />
        </service>
    </services>
</configuration>
    可以看见其实所谓的configuration其实就是每个组件对应的xml配置:
    每个组件services配置以componentName.services开头
    services.instances指定组件名字
    *.class指定引用到的相关services
    把webx-default.xml读取到内存:读取"/WEB-INF/webx-default.xml"文件,获取URL为:"jndi:/localhost/WEB-INF/webx-default.xml"(从这里看出,代码是先加载各个组件的webx.xml再去加载webx-default.xml)。
    配置main-instance的内容:获取所有的main-instance服务,这里的服务器是指webx-default.xml中的services配置,如果这些services还没添加到公共的configuration的配置文件(说明:刚才把所有的组件配置都存储到这里了),通过循环把main-instances services组件及配置添加到这里(注意:这里的Services配置必须是非"."号分割的,要不然代码将无法获取到这些services配置)
    配置sub-instance的内容:在e)中,代码已经将所有组件配置都放到了configuration中,在配置sub-instance时,为每个组件配置对应的sub-instance内容,以home为例:home.services.JspService.class=com.alibaba.service.jsp.DefaultJspService。这样我们就发现,其实所谓的sub-instance只是所有组件的公共配置而已,如果组件本身包含了对应的内容,则不再包含sub-instance中的内容。(注:这里说的重复配置项包括service以及其属性配置)
    配置main-instance的非services配置项:exodus2中没有作这块配置
    配置sub-instance的非services配置项:exodus2中没有作这块配置
    向配置添加一个新的配置项key/value如下:services.ThreadContextService.factory.default=com.alibaba.webx.service.rundata.RunDataObjectFactory
    到这一步,configuration添加webx-default.xml中services内容,同时把各个组件中的services给初始化好

f) 初始化serviceManager
    获取manager配置类名:去web.xml容器查找"service.manager.class"的值,exodus2目前没配置,采用scheme中默认的serviceManager容器名"com.alibaba.webx.service.DefaultWebxServiceManager"
    获取manger实例:通过classLoader获取manager对象
    配置servicesManager:设置bootstrapResourceLoaderService为resourceLoader,设置configuration为一直配置的配置项保存地址。
    初始化servicesManager:
        创建service名称和service配置的映射:
            初始化以下几个属性:instanceNames、instanceContexts、instanceConfigurations、services、serviceNames
        初始化resource Loader services.class
            创建main-instance中的ResourceLoaderService对象
            为每个组件创建ResourceLoaderService对象
            创建过程:首先从services获取ServiceInstance,再调用ServiceInstance的获取实例对象获取具体的service。
        初始化earlyInit的services
    把webxLoader对象以key/value形式存储在servicesManager的attribute对象中,key为webx.controller
    注意:这里有必要仔细看一下DefautlServiceManager.services属性的创建过程,该属性包含了所有service对象,services以键值对存储serviceInstances对象。serviceInstances的serviceInstanceContext包含了具体services对象。代码中通过传要初始化的servicesName调用 DefaultServiceManager.this.createServiceInstanceContext获取serviceInstances实例。查看代码最终是调用new DefaultWebxComponent(this, instanceName)产生ServiceInstanceContext。
    
g) 配置其他webxController
    rundataServices的实例化
    threadContextService实例化
    componetNames实例化
    components实例化,value是ServiceInstanceContext
    把webxLoader的引用以key为webx.controller放到servletContext中去
h) 是否选择实例化所有的services
    调用DefaultServiceManager去初始化所有的services,exodus2默认配置初始化所有services

webxControllerServlet:
这样,webxLoader实例就建立起来了。在webxControllerServlet中通过获取servletContext获取到具体的对象。
并把webx.controller.servlet.config=getServletConfig()以建值对放到getServletConfig()中

这样webxLoader就初始化好了。
下一个note将重点介绍ServicesManager创建和ServicesManager创建services的过程。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值