版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
..StrutsPrepareAndExecuteFilter實現(xiàn)了Filter接口
init方法為初始化入口StrutsPrepareAndExecuteFilterinit方法
publicvoid
init<FilterConfig
filterConfig>
throws
ServletException
{
//初始化輔助類
類似一個Delegate
InitOperations
init
=
new
InitOperations<>;
try
{
//
FilterHostConfig
封裝了FilterConfig參數(shù)對象
FilterHostConfig
config
=
new
FilterHostConfig<filterConfig>;
//LoggerFactory配置加載
//如果失敗
使用JdkLoggerFactory//TODO
SPI
init.initLogging<config>;
//TODO
創(chuàng)建Dispatcher
注冊加載器
執(zhí)行加載器
創(chuàng)建容器
解析xml
Dispatcher
dispatcher
=
init.initDispatcher<config>;
init.initStaticContentLoader<config,
dispatcher>;
//預(yù)處理類
請求處理時才會真正用到//1.主要負(fù)責(zé)在每次請求
創(chuàng)建ActionContext
清除ActionContext//2.當(dāng)接收到一個請求時
通過uri查找
ActionConfig
創(chuàng)建ActionMapping
prepare
=
new
PrepareOperations<filterConfig.getServletContext<>,
dispatcher>;
//處理請求
Delegate
execute
=
new
ExecuteOperations<filterConfig.getServletContext<>,
dispatcher>;
this.excludedPatterns
=
init.buildExcludedPatternsList<dispatcher>;
//空實現(xiàn)
留作擴(kuò)展
postInit<dispatcher,
filterConfig>;
}
finally
{
init.cleanup<>;
}
}
InitOperations類似與一個Delegate主要負(fù)責(zé)實例化Dispatche
再把初始化操作轉(zhuǎn)交給Dispatcheinit處理public
Dispatcher
initDispatcher<
HostConfig
filterConfig
>
{
//創(chuàng)建Dispatcher
Dispatcher
dispatcher
=
createDispatcher<filterConfig>;
//核心方法
Container容器的創(chuàng)建
xml解析在此方法發(fā)生
dispatcher.init<>;
return
dispatcher;
}
private
Dispatcher
createDispatcher<
HostConfig
filterConfig
>
{
Map<String,
String>
params
=
new
HashMap<String,
String><>;
for
<
Iterator
e
=
filterConfig.getInitParameterNames<>;
e.hasNext<>;
>
{
String
name
=
<String>
e.next<>;
String
value
=
filterConfig.getInitParameter<name>;
params.put<name,
value>;
}
returnnew
Dispatcher<filterConfig.getServletContext<>,
params>;
}
Dispatcherinit方法
1.針對配置文件注冊不同的加載器保存到ConfigurationManager類中的一個變量中
2.創(chuàng)建容器解析xmlpublicvoid
init<>
{
//創(chuàng)建配置操作管理類
,
會保存元素加載器
if
<configurationManager
==
null>
{
configurationManager
=
createConfigurationManager<BeanSelectionProvider.DEFAULT_BEAN_NAME>;
}
try
{
/**初始化各種形式加載器,保存到ConfigurationManager#containerProviders
Map集合中
沒有真正執(zhí)行加載
解析邏輯*///org/apache/struts2/perties屬性文件
里面定義了一系列struts常量
init_DefaultProperties<>;
//
[1]//web.xml配置的
config參數(shù)
[配置多個用","分開]//如果沒有該參數(shù)
默認(rèn)為
struts-default.xml[框架級],struts-plugin.xml[框架級],struts.xml[系統(tǒng)級別]//根據(jù)文件名稱
創(chuàng)建加載器
加載xml主要有一下兩個解析器//XmlConfigurationProvider[xwork.xml],//StrutsXmlConfigurationProvider[struts相關(guān)配置文件]配置元素加載器
init_TraditionalXmlConfigurations<>;
//
[2]//struts.locale
注冊
init_LegacyStrutsProperties<>;
//
[3]//實例化
我們自定義的加載器
保存到containerProviders集合中//
web.xml
configProviders參數(shù)
多個用","分開
//配置器必須是ConfigurationProvider接口的實例//TODO
SPI
init_CustomConfigurationProviders<>;
//
[5]//web.xml配置的init-param參數(shù)
加載器
最終會保存到Container容器中
init_FilterInitParameters<>
;
//
[6]//TODO
根據(jù)我們在struts.xml定義的
常量
選擇插件類
//比如集成spring
會用到org.apache.struts2.spring.StrutsSpringObjectFactory
init_AliasStandardObjects<>
;
//
[7]/**
執(zhí)行加載器
*///TODO
創(chuàng)建容器
解析xml
真正執(zhí)行加載器方法
Container
container
=
init_PreloadConfiguration<>;
//執(zhí)行當(dāng)前Dispatcher對象
依賴關(guān)系注入
container.inject<this>;
//額外動作
init_CheckConfigurationReloading<container>;
init_CheckWebLogicWorkaround<container>;
}
catch
<Exception
ex>
{
if
<LOG.isErrorEnabled<>>
LOG.error<"Dispatcher
initialization
failed",
ex>;
thrownew
StrutsException<ex>;
}
}
ConfigurationManager主要管理創(chuàng)建的各種加載器publicclass
ConfigurationManager
{
protectedstaticfinal
Logger
LOG
=
LoggerFactory.getLogger<ConfigurationManager.class>;
//配置元素管理器protected
Configuration
configuration;
protected
Lock
providerLock
=
new
ReentrantLock<>;
//創(chuàng)建的xml加載器會保存到次集合中private
List<ContainerProvider>
containerProviders
=
new
CopyOnWriteArrayList<ContainerProvider><>;
}
Dispatcher的createConfigurationManager方法protected
ConfigurationManager
createConfigurationManager<String
name>
{
//name
-
>
strutsreturnnew
ConfigurationManager<name>;
}
/r/perties
屬性文件加載器privatevoid
init_DefaultProperties<>
{
//保存到ConfigurationManager加載器集合中
configurationManager.addConfigurationProvider<new
DefaultPropertiesProvider<>>;
}
2.創(chuàng)建struts相關(guān)文件加載器StrutsXmlConfigurationProvider
privatevoid
init_TraditionalXmlConfigurations<>
{
//web.xml
配置的config
String
configPaths
=
initParams.get<"config">;
if
<configPaths
==
null>
{
//如果沒有配置
默認(rèn)
struts-default.xml,struts-plugin.xml,struts.xml
configPaths
=
DEFAULT_CONFIGURATION_PATHS;
}
String[]
files
=
configPaths.split<"\\s*[,]\\s*">;
for
<String
file
:
files>
{
if
<file.endsWith<".xml">>
{
if
<"xwork.xml".equals<file>>
{
configurationManager.addConfigurationProvider<createXmlConfigurationProvider<file,
false>>;
}
else
{
//struts
xml加載器
//StrutsXmlConfigurationProvider
configurationManager.addConfigurationProvider<createStrutsXmlConfigurationProvider<file,
false,
servletContext>>;
}
}
else
{
thrownew
IllegalArgumentException<"Invalid
configuration
file
name">;
}
}
}
protected
XmlConfigurationProvider
createXmlConfigurationProvider<String
filename,
boolean
errorIfMissing>
{
returnnew
XmlConfigurationProvider<filename,
errorIfMissing>;
}
protected
XmlConfigurationProvider
createStrutsXmlConfigurationProvider<String
filename,
boolean
errorIfMissing,
ServletContext
ctx>
{
returnnew
StrutsXmlConfigurationProvider<filename,
errorIfMissing,
ctx>;
}
3.web.xml擴(kuò)展的ContainerProviders加載器實例化privatevoid
init_CustomConfigurationProviders<>
{
//web.xml
中configProviders
節(jié)點
String
configProvs
=
initParams.get<"configProviders">;
if
<configProvs
!=
null>
{
String[]
classes
=
configProvs.split<"\\s*[,]\\s*">;
for
<String
cname
:
classes>
{
Class
cls
=
ClassLoaderUtils.loadClass<cname,
this.getClass<>>;
ConfigurationProvider
prov
=
<ConfigurationProvider>cls.newInstance<>;
configurationManager.addConfigurationProvider<prov>;
}
}
}
init_PreloadConfiguration
方法主要完成創(chuàng)建容器,解析xml動作private
Container
init_PreloadConfiguration<>
{
//創(chuàng)建Container
解析xml
Configuration
config
=
configurationManager.getConfiguration<>;
Container
container
=
config.getContainer<>;
boolean
reloadi18n
=
Boolean.valueOf<container.getInstance<String.class,
StrutsConstants.STRUTS_I18N_RELOAD>>;
LocalizedTextUtil.setReloadBundles<reloadi18n>;
return
container;
}
init_PreloadConfiguration方法中調(diào)用了
ConfigurationManager的getConfiguration方法publicsynchronized
Configuration
getConfiguration<>
{
//創(chuàng)建配置元素管理器if
<configuration
==
null>
{
//
defaultFrameworkBeanName
-
>
struts
setConfiguration<createConfiguration<defaultFrameworkBeanName>>;
try
{
//
getContainerProviders
返回注冊的各種加載器
//
reloadContainer
創(chuàng)建Container
解析xml
configuration.reloadContainer<getContainerProviders<>>;
}
catch
<ConfigurationException
e>
{
setConfiguration<null>;
thrownew
ConfigurationException<"Unable
to
load
configuration.",
e>;
}
}
else
{
conditionalReload<>;
}
return
configuration;
}
[java]viewplaincopyprint?protected
Configuration
createConfiguration<String
beanName>
{
returnnew
DefaultConfiguration<beanName>;
}
DefaultConfiguration的reloadContainer方法會去執(zhí)行已注冊的各種加載器
,和創(chuàng)建容器publicsynchronized
List<PackageProvider>
reloadContainer<List<ContainerProvider>
providers>
throws
ConfigurationException
{
packageContexts.clear<>;
loadedFileNames.clear<>;
List<PackageProvider>
packageProviders
=
new
ArrayList<PackageProvider><>;
//
保存struts常量
ContainerProperties
props
=
new
ContainerProperties<>;
//容器構(gòu)建器
ContainerBuilder
builder
=
new
ContainerBuilder<>;
for
<final
ContainerProvider
containerProvider
:
providers>
{
/**
*
初始化Document
準(zhǔn)備解析
*
具體在XmlConfigurationProvider實現(xiàn)類
會處理include節(jié)點
*
處理完成之后Document會保存到XmlConfigurationProvider#documents
list集合中
*
include
file路徑會保存到XmlConfigurationProvider#loadedFileUrls
set集合中
*
從代碼中發(fā)現(xiàn)
include
file屬性中
可以使用通配符
"*"
*//**
StrutsXmlConfigurationProvider
是
XmlConfigurationProvider的子類
*//**
StrutsXmlConfigurationProvider
struts*.xml
*/
containerProvider.init<this>;
//針對"bean","constant","unknown-handler-stack"節(jié)點
不包括"package"節(jié)點
解析xml
//每一個bean
對應(yīng)一個LocatableFactory
LocatableFactory保存了bean的定義//bean定義
保存到ContainerBuilder#factories
map集合中
//配置文件中定義的常量
保存到props中
containerProvider.register<builder,
props>;
}
//將常量保存到ContainerBuilder#factories
map集合中
//每一個常量對應(yīng)一個LocatableConstantFactory
props.setConstants<builder>;
builder.factory<Configuration.class,
new
Factory<Configuration><>
{
public
Configuration
create<Context
context>
throws
Exception
{
return
DefaultConfiguration.this;
}
}>;
ActionContext
oldContext
=
ActionContext.getContext<>;
try
{
//創(chuàng)建輔助容器
ContainerImpl并且
實例化
struts一些核心類
Container
bootstrap
=
createBootstrapContainer<>;
setContext<bootstrap>;
//主容器
這是一個全局變量
container
=
builder.create<false>;
setContext<container>;
objectFactory
=
container.getInstance<ObjectFactory.class>;
//
Process
the
configuration
providers
firstfor
<final
ContainerProvider
containerProvider
:
providers>
{
if
<containerProvider
instanceof
PackageProvider>
{
//viders.XmlConfigurationProvider#setObjectFactory<ObjectFactory>
container.inject<containerProvider>;
//解析
xml
package節(jié)點//保存packageContexts
map集合中//viders.XmlConfigurationProvider
line
481
<<PackageProvider>
containerProvider>.loadPackages<>;
packageProviders.add<<PackageProvider>
containerProvider>;
}
}
//
Then
process
any
package
providers
from
the
plugins
Set<String>
packageProviderNames
=
container.getInstanceNames<PackageProvider.class>;
if
<packageProviderNames
!=
null>
{
for
<String
name
:
packageProviderNames>
{
PackageProvider
provider
=
container.getInstance<PackageProvider.class,
name>;
provider.init<this>;
provider.loadPackages<>;
packageProviders.add<provider>;
}
}
//TODO
rebuildRuntimeConfiguration<>;
}
finally
{
if
<oldContext
==
null>
{
ActionContext.setContext<null>;
}
}
return
packageProviders;
}
StrutsXmlConfigurationProvider的init方法具體在父類XmlConfigurationProvider中實現(xiàn)publicvoid
init<Configuration
configuration>
{
this.configuration
=
configuration;
this.includedFileNames
=
configuration.getLoadedFileNames<>;
//
configFileName
->struts.xml//1.遞歸處理include節(jié)點//2.生成Document
集合
loadDocuments<configFileName>;
}
loadDocuments方法中調(diào)用了loadConfigurationFiles方法
返回一個Document集合privatevoid
loadDocuments<String
configFileName>
{
loadedFileUrls.clear<>;
//List<Document>
documents
documents
=
loadConfigurationFiles<configFileName,
null>;
}
loadConfigurationFiles方法遞歸處理include節(jié)點最終生成Document集合private
List<Document>
loadConfigurationFiles<String
fileName,
Element
includeElement>
{
List<Document>
docs
=
new
ArrayList<Document><>;
List<Document>
finalDocs
=
new
ArrayList<Document><>;
//防止include重復(fù)引入if
<!includedFileNames.contains<fileName>>
{
if
<LOG.isDebugEnabled<>>
{
LOG.debug<"Loading
action
configurations
from:
"
+
fileName>;
}
includedFileNames.add<fileName>;
Iterator<URL>
urls
=
null;
InputStream
is
=
null;
IOException
ioException
=
null;
try
{
urls
=
getConfigurationUrls<fileName>;
}
catch
<IOException
ex>
{
ioException
=
ex;
}
if
<urls
==
null
||
!urls.hasNext<>>
{
if
<errorIfMissing>
{
thrownew
ConfigurationException<"Could
not
open
files
of
the
name
"
+
fileName,
ioException>;
}
else
{
LOG.info<"Unable
to
locate
configuration
files
of
the
name
"
+
fileName
+
",
skipping">;
return
docs;
}
}
URL
url
=
null;
while
<urls.hasNext<>>
{
try
{
url
=
urls.next<>;
is
=
FileManager.loadFile<url>;
InputSource
in
=
new
InputSource<is>;
in.setSystemId<url.toString<>>;
//生成Document對象
docs.add<DomHelper.parse<in,
dtdMappings>>;
}
catch
<XWorkException
e>
{
if
<includeElement
!=
null>
{
thrownew
ConfigurationException<"Unable
to
load
"
+
url,
e,
includeElement>;
}
else
{
thrownew
ConfigurationException<"Unable
to
load
"
+
url,
e>;
}
}
catch
<Exception
e>
{
final
String
s
=
"Caught
exception
while
loading
file
"
+
fileName;
thrownew
ConfigurationException<s,
e,
includeElement>;
}
finally
{
if
<is
!=
null>
{
try
{
is.close<>;
}
catch
<IOException
e>
{
LOG.error<"Unable
to
close
input
stream",
e>;
}
}
}
}
//sort
the
documents,
according
to
the
"order"
attribute
Collections.sort<docs,
new
Comparator<Document><>
{
publicint
compare<Document
doc1,
Document
doc2>
{
return
XmlHelper.getLoadOrder<doc1>.compareTo<XmlHelper.getLoadOrder<doc2>>;
}
}>;
for
<Document
doc
:
docs>
{
Element
rootElement
=
doc.getDocumentElement<>;
NodeList
children
=
rootElement.getChildNodes<>;
int
childSize
=
children.getLength<>;
for
<int
i
=
0;
i
<
childSize;
i++>
{
Node
childNode
=
children.item<i>;
if
<childNode
instanceof
Element>
{
Element
child
=
<Element>
childNode;
final
String
nodeName
=
child.getNodeName<>;
if
<"include".equals<nodeName>>
{
String
includeFileName
=
child.getAttribute<"file">;
//可以使用通配符匹配
if
<includeFileName.indexOf<'*'>
!=
-1>
{
ClassPathFinder
wildcardFinder
=
new
ClassPathFinder<>;
wildcardFinder.setPattern<includeFileName>;
Vector<String>
wildcardMatches
=
wildcardFinder.findMatches<>;
for
<String
match
:
wildcardMatches>
{
//遞歸處理include節(jié)點
finalDocs.addAll<loadConfigurationFiles<match,
child>>;
}
}
else
{
//遞歸處理include節(jié)點finalDocs.addAll<loadConfigurationFiles<includeFileName,
child>>;
}
}
}
}
finalDocs.add<doc>;
loadedFileUrls.add<url.toString<>>;
}
}
return
finalDocs;
}
StrutsXmlConfigurationProvider的register方法主要在父類XmlConfigurationProvider中實現(xiàn)1.遍歷init方法中生成的Document
集合
解析xml文件中定義的bean,constant常量節(jié)點不會處理package節(jié)點2.解析bean節(jié)點的值包裝成LocatableFactory對象
注冊到ContainerBuilder中factoriesmap集合中3.解析constant節(jié)點的值保存到ContainerProperties對象中
XmlConfigurationProvider的register
這里只解析bean
,constant節(jié)點publicvoid
register<ContainerBuilder
containerBuilder,
LocatableProperties
props>
throws
ConfigurationException
{
Map<String,
Node>
loadedBeans
=
new
HashMap<String,
Node><>;
for
<Document
doc
:
documents>
{
Element
rootElement
=
doc.getDocumentElement<>;
NodeList
children
=
rootElement.getChildNodes<>;
int
childSize
=
children.getLength<>;
for
<int
i
=
0;
i
<
childSize;
i++>
{
Node
childNode
=
children.item<i>;
if
<childNode
instanceof
Element>
{
Element
child
=
<Element>
childNode;
final
String
nodeName
=
child.getNodeName<>;
//解析bean節(jié)點if
<"bean".equals<nodeName>>
{
String
type
=
child.getAttribute<"type">;
String
name
=
child.getAttribute<"name">;
String
impl
=
child.getAttribute<"class">;
String
onlyStatic
=
child.getAttribute<"static">;
String
scopeStr
=
child.getAttribute<"scope">;
boolean
optional
=
"true".equals<child.getAttribute<"optional">>;
Scope
scope
=
Scope.SINGLETON;
if
<"default".equals<scopeStr>>
{
scope
=
Scope.DEFAULT;
}
elseif
<"request".equals<scopeStr>>
{
scope
=
Scope.REQUEST;
}
elseif
<"session".equals<scopeStr>>
{
scope
=
Scope.SESSION;
}
elseif
<"singleton".equals<scopeStr>>
{
scope
=
Scope.SINGLETON;
}
elseif
<"thread".equals<scopeStr>>
{
scope
=
Scope.THREAD;
}
if
<StringUtils.isEmpty<name>>
{
name
=
Container.DEFAULT_NAME;
}
try
{
Class
cimpl
=
ClassLoaderUtil.loadClass<impl,
getClass<>>;
Class
ctype
=
cimpl;
if
<StringUtils.isNotEmpty<type>>
{
ctype
=
ClassLoaderUtil.loadClass<type,
getClass<>>;
}
if
<"true".equals<onlyStatic>>
{
//
Force
loading
of
class
to
detect
no
class
def
found
exceptions
cimpl.getDeclaredClasses<>;
containerBuilder.injectStatics<cimpl>;
}
else
{
//
beanName
+
class
構(gòu)成唯一約束
if
<containerBuilder.contains<ctype,
name>>
{
//用loadedBeans
map集合檢查是否有重復(fù)配置的beanLocation
loc
=
LocationUtils.getLocation<loadedBeans.get<ctype.getName<>
+
name>>;
if
<throwExceptionOnDuplicateBeans>
{
thrownew
ConfigurationException<"Bean
type
"
+
ctype
+
"
with
the
name
"
+
name
+
"
has
already
been
loaded
by
"
+
loc,
child>;
}
}
//
Force
loading
of
class
to
detect
no
class
def
found
exceptions
cimpl.getDeclaredConstructors<>;
if
<LOG.isDebugEnabled<>>
{
LOG.debug<"Loaded
type:"
+
type
+
"
name:"
+
name
+
"
impl:"
+
impl>;
}
//LocatableFactory
類似spring中
BeanDefinition
//bean定義
保存到ContainerBuilder#factories
map集合中//目前為止
并未真正實例化beancontainerBuilder.factory<ctype,
name,
new
LocatableFactory<name,
ctype,
cimpl,
scope,
childNode>,
scope>;
}
//loadedBeans
檢查重復(fù)配置的bean
loadedBeans.put<ctype.getName<>
+
name,
child>;
}
catch
<Throwable
ex>
{
if
<!optional>
{
thrownew
ConfigurationException<"Unable
to
load
bean:
type:"
+
type
+
"
class:"
+
impl,
ex,
childNode>;
}
else
{
LOG.debug<"Unable
to
load
optional
class:
"
+
ex>;
}
}
//constant常量節(jié)點
}
elseif
<"constant".equals<nodeName>>
{
String
name
=
child.getAttribute<"name">;
String
value
=
child.getAttribute<"value">;
//ContainerProperties
->props
props.setProperty<name,
value,
childNode>;
}
elseif
<nodeName.equals<"unknown-handler-stack">>
{
List<UnknownHandlerConfig>
unknownHandlerStack
=
new
ArrayList<UnknownHandlerConfig><>;
NodeList
unknownHandlers
=
child.getElementsByTagName<"unknown-handler-ref">;
int
unknownHandlersSize
=
unknownHandlers.getLength<>;
for
<int
k
=
0;
k
<
unknownHandlersSize;
k++>
{
Element
unknownHandler
=
<Element>
unknownHandlers.item<k>;
unknownHandlerStack.add<new
UnknownHandlerConfig<unknownHandler.getAttribute<"name">>>;
}
if
<!unknownHandlerStack.isEmpty<>>
configuration.setUnknownHandlerStack<unknownHandlerStack>;
}
}
}
}
}
XmlConfigurationProvider的loadPackages方法
解析package節(jié)點下的所有子節(jié)點interceptor
,ResultType等等
保存到DefaultConfigurationpackageContextsmap集合中publicvoid
loadPackages<>
throws
ConfigurationException
{
List<Element>
reloads
=
new
ArrayList<Element><>;
for
<Document
doc
:
documents>
{
Element
rootElement
=
doc.getDocumentElement<>;
NodeList
children
=
rootElement.getChildNodes<>;
int
childSize
=
children.getLength<>;
for
<int
i
=
0;
i
<
childSize;
i++>
{
Node
childNode
=
children.item<i>;
if
<childNode
instanceof
Element>
{
Element
child
=
<Element>
childNode;
final
String
nodeName
=
child.getNodeName<>;
if
<"package".equals<nodeName>>
{
//解析package節(jié)點
包裝成PackageConfig對象
PackageConfig
cfg
=
addPackage<child>;
if
<cfg.isNeedsRefresh<>>
{
reloads.add<child>;
}
}
}
}
//空實現(xiàn)
擴(kuò)展時用
loadExtraConfiguration<doc>;
}
if
<reloads.size<>
>
0>
{
reloadRequiredPackages<reloads>;
}
for
<Document
doc
:
documents>
{
//空實現(xiàn)
擴(kuò)展時用
loadExtraConfiguration<doc>;
}
documents.clear<>;
configuration
=
null;
}
package節(jié)點下的所有子節(jié)點protected
PackageConfig
addPackage<Element
packageElement>
throws
ConfigurationException
{PackageConfig.Builder
newPackage
=
buildPackageContext<packageElement>;
if
<newPackage.isNeedsRefresh<>>
{
return
newPackage.build<>;
}
//處理所有的ResultType
包括自定義的
,
strust-default.xml中定義的
addResultTypes<newPackage,
packageElement>;
//interceptor節(jié)點
loadInterceptors<newPackage,
packageElement>;
//default-interceptor-ref
loadDefaultInterceptorRef<newPackage,
packageElement>;
//default-class-ref節(jié)點
loadDefaultClassRef<newPackage,
packageElement>;
//全局result
global-results節(jié)點
loadGlobalResults<newPackage,
packageElement>;
//global-exception-mappings節(jié)點
異常處理
loadGobalExceptionMappings<newPackage,
packageElement>;
NodeList
actionList
=
packageElement.getElementsByTagName<"action">;
for
<int
i
=
0;
i
<
actionList.getLength<>;
i++>
{
Element
actionElement
=
<Element>
actionList.item<i>;
//
action節(jié)點
result節(jié)點處理
addAction<actionElement,
newPackage>;
}
//default-action-ref
loadDefaultActionRef<newPackage,
packageElement>;
PackageConfig
cfg
=
newPackage.build<>;
//TODO
保存到Map<string
packageconfig="">
packageContexts
集合中
configuration.addPackageConfig<cfg.getName<>,
cfg>;
return
cfg;
}</string>
最后整理解析的ActionConfigMap集合[DefaultConfiguration#packageContexts]
最終已Map<nameSpace,Map<actionName,ActionConfig>>形式存儲publicvoid
rebuildRuntimeConfiguration<>
{
runtimeConfiguration
=
buildRuntimeConfiguration<>;
}
[java]protectedsynchronized
RuntimeConfiguration
buildRuntimeConfiguration<>
throws
ConfigurationException
{
Map<String,
Map<String,
ActionConfig>>
namespaceActionConfigs
=
new
LinkedHashMap<String,
Map<String,
ActionConfig>><>;
Map<String,
String>
namespaceConfigs
=
new
LinkedHashMap<String,
String><>;
for
<PackageConfig
packageConfi
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 幼兒教師實操培訓(xùn)
- 電力行業(yè)營銷創(chuàng)新經(jīng)驗交流
- 財務(wù)指標(biāo)監(jiān)控與預(yù)警體系計劃
- 市場研究公司前臺服務(wù)總結(jié)
- 2024學(xué)年北師大附屬實驗高二數(shù)學(xué)上學(xué)期期末模擬試卷附答案解析
- 被惡意退款協(xié)議書合同范本
- 貝殼房屋解決合同
- 申請pos機(jī)時一定要注意的四個現(xiàn)象
- 二零二五年度教育科技合作伙伴人才培養(yǎng)協(xié)議3篇
- 2025年無錫貨運(yùn)從業(yè)資格證考些什么內(nèi)容
- 新人教版一年級數(shù)學(xué)下冊全冊導(dǎo)學(xué)案
- 2025年中考語文復(fù)習(xí)之現(xiàn)代文閱讀:非連續(xù)性文本閱讀(10題)
- GB/T 9755-2024合成樹脂乳液墻面涂料
- 2024年度軟件定制開發(fā)合同(ERP系統(tǒng))3篇
- 家族族譜模板
- (正式版)JBT 10437-2024 電線電纜用可交聯(lián)聚乙烯絕緣料
- 教科版三年級上冊科學(xué)期末測試卷(二)【含答案】
- 古詩詞常見的修辭手法講課教案
- 科研項目評審評分表
- A5技術(shù)支持的課堂導(dǎo)入作業(yè)1—問題描述.針對日常教學(xué)中的某一主題針對教學(xué)目標(biāo)、教學(xué)內(nèi)容以及教學(xué)對象用簡短的語言描述當(dāng)前課堂導(dǎo)入環(huán)節(jié)中存在的問題和不足以及借助信息技術(shù)改進(jìn)課堂導(dǎo)入的必要性
- 國家開放大學(xué)《土木工程力學(xué)(本)》章節(jié)測試參考答案
評論
0/150
提交評論