您好,欢迎来到测品娱乐。
搜索
您的当前位置:首页struts源码分析

struts源码分析

来源:测品娱乐
Strus2源码分析

一, org.apache.struts2.dispatcher.FilterDispatcher 初始化

public void init(FilterConfig filterConfig) throws ServletException {

try {

this.filterConfig = filterConfig;

initLogging();

dispatcher = createDispatcher(filterConfig); //初始化dispatcher dispatcher.init();

dispatcher.getContainer().inject(this);

staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));

} finally {

ActionContext.setContext(null); }

}

//下面就是初始化dispatcher public void init() {

if (configurationManager == null) {

;

}

try {

//加载org/apache/struts2/default.properties init_DefaultProperties(); // [1]

//首先读取web.xml中的config初始参数值

//如果没有配置就使用默认的\"struts-default.xml,struts-plugin.xml,struts.xml\" init_TraditionalXmlConfigurations(); // [2] init_LegacyStrutsProperties(); // [3] //加载Web.xml中配置的xml

init_CustomConfigurationProviders(); // [5] init_FilterInitParameters() ; // [6] init_AliasStandardObjects() ; // [7]

Container container = init_PreloadConfiguration(); container.inject(this);

configurationManager = new

ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME)

init_CheckConfigurationReloading(container); init_CheckWebLogicWorkaround(container);

if (!dispatcherListeners.isEmpty()) {

for (DispatcherListener l : dispatcherListeners) { l.dispatcherInitialized(this); } }

} catch (Exception ex) { if (LOG.isErrorEnabled())

LOG.error(\"Dispatcher initialization failed\", ex); throw new StrutsException(ex); }

}

二,

Struts2请求流程

1、客户端发送请求

2、请求先通过ActionContextCleanUp-->FilterDispatcher 3、FilterDispatcher创建ActionMapping 和serviceAction

ActionMapping设置扩展名,Namespace,ActionName,Method(这里只处理!请示的方法如user!aadd.action)

ServiceAction创建ActionProxy代理,执行代理

4、ActionProxy 准备工作(1)、查找命名空间,在空间中查找对应的Action [查找方法:

是先安全名匹配Action,如果没有则按类拟与user-*这种形式匹配],如果找到装载Action 中的配置

(2)在Action类中查找对应的方法,如果没有则用execute方法

(3)初始化Action (方法先找Bean中是否有,如果没有则跟据类实例化)

5、ActionProxy创建一个ActionInvocation的实例,ActionInvocation调用真正的Action,当然这涉及到相关的调用(其中有参数封装,封装异常等等,最后一个是调用Action)

6、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener。添加PreResultListener可以在Interceptor中实现,

7、ResultCode跟据返回的值,查找对应ResultConfig对象(查找方法先跟据Name找,如果没有则查找*的)跟据不用的Type配置,得到不同的resultClassName,实后实列化并设置参数,调用doExecute方法返回

注:resultClassName有以后几种 Type默认时:

resultClassName=

org.apache.struts2.dispatcher.ServletDispatcherResult Type=redirectAction resultClassName=

org.apache.struts2.dispatcher.ServletActionRedirectResult Type=tiles

resultClassName=org.apache.struts2.views.tiles.TilesResult

对应调用的方法: Forword Redirect Render

8、Struts2的查找值和设置值都是使用Ognl来实现的。关于Ognl的介绍可以到其官方

网站查看http://www.ognl.org/

这样,一个Struts2的请求流程基本上就结束了

mapping=actionMapper.getMapping(request, dispatcher.getConfigurationManager());

//创始ActionMapping

public ActionMapping getMapping(HttpServletRequest request, ConfigurationManager configManager) { ActionMapping mapping = new ActionMapping(); String uri = getUri(request);//得到请示Url

int indexOfSemicolon = uri.indexOf(\";\");

uri = (indexOfSemicolon > -1) ? uri.substring(0, indexOfSemicolon) : uri;

uri = dropExtension(uri, mapping);//去掉后缀 if (uri == null) { return null; }

//设置NameSpance和ActionName

parseNameAndNamespace(uri, mapping, configManager);

handleSpecialParameters(request, mapping);

if (mapping.getName() == null) { return null; }

//处理以!的方法

parseActionName(mapping);

return mapping;

}

//ServiceAction方法

dispatcher.serviceAction(request,response,servletContext,mapping);

public void serviceAction(HttpServletRequest request, HttpServletResponse response, ServletContext context, ActionMapping mapping) throws ServletException {

Map extraContext = createContextMap(request, response, mapping, context);

// If there was a previous value stack, then create a new copy and pass it in to be used by the new Action ValueStack stack = (ValueStack)

request.getAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY); boolean nullStack = stack == null; if (nullStack) {

ActionContext ctx = ActionContext.getContext(); if (ctx != null) {

stack = ctx.getValueStack(); } }

if (stack != null) {

extraContext.put(ActionContext.VALUE_STACK, valueStackFactory.createValueStack(stack)); }

String timerKey = \"Handling request from Dispatcher\"; try {

UtilTimerStack.push(timerKey);

String namespace = mapping.getNamespace(); String name = mapping.getName(); String method = mapping.getMethod();

Configuration config =

configurationManager.getConfiguration(); //创建Acton 代理

ActionProxy proxy =

config.getContainer().getInstance(ActionProxyFactory.class).createActionProxy(

namespace, name, method, extraContext, true, false);

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, proxy.getInvocation().getStack());

// if the ActionMapping says to go straight to a result, do it! if (mapping.getResult() != null) { Result result = mapping.getResult(); result.execute(proxy.getInvocation()); } else {

proxy.execute(); }

// If there was a previous value stack then set it back onto the request

if (!nullStack) {

request.setAttribute(ServletActionContext.STRUTS_VALUESTACK_KEY, stack); }

} catch (ConfigurationException e) { // WW-2874 Only log error if in devMode if(devMode) { } else { }

sendError(request, response, context, HttpServletResponse.SC_NOT_FOUND, e);

LOG.warn(\"Could not find action or result\", e); LOG.error(\"Could not find action or result\", e);

} catch (Exception e) {

sendError(request, response, context, HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e); } finally {

UtilTimerStack.pop(timerKey); }

}

//准备代理

proxy.prepare();

protected void prepare() {

String profileKey = \"create DefaultActionProxy: \"; try {

UtilTimerStack.push(profileKey); //查找匹配的ActionConfig对象

//查找命名空间,在空间中查找对应的Action [查找方法:是先安全名匹配Action,如果没//有则按类拟与user-*这种形式匹配],如果找到装载Action 中的配置

config =

configuration.getRuntimeConfiguration().getActionConfig(namespace, actionName);

if (config == null &&

unknownHandlerManager.hasUnknownHandlers()) { config =

unknownHandlerManager.handleUnknownAction(namespace, actionName); }

if (config == null) { String message;

if ((namespace != null) && (namespace.trim().length() > 0)) {

message =

LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_PACKAGE_ACTION_EXCEPTION, Locale.getDefault(), new String[]{ namespace, actionName }); } else { message =

LocalizedTextUtil.findDefaultText(XWorkMessages.MISSING_ACTION_EXCEPTION, Locale.getDefault(), new String[]{ actionName }); }

throw new ConfigurationException(message); }

//在Action类中查找对应的方法,如果没有则用execute方法 resolveMethod();

if (!config.isAllowedMethod(method)) {

throw new ConfigurationException(\"Invalid method: \"+method+\" for action \"+actionName); }

//初始代理

invocation.init(this);

} finally {

UtilTimerStack.pop(profileKey);

}

//创始Action

public Object buildBean(String beanName, Map extraContext, boolean injectInternal) throws Exception { Object o = null; try {

o = appContext.getBean(beanName);

} catch (NoSuchBeanDefinitionException e) { Class beanClazz = getClassInstance(beanName); o = buildBean(beanClazz, extraContext); }

if (injectInternal) { injectInternalBeans(o); }

return o;

}

//执行代理

proxy.execute();

public String invoke() throws Exception { String profileKey = \"invoke: \"; try {

UtilTimerStack.push(profileKey);

if (executed) {

throw new IllegalStateException(\"Action has already executed\");

}

if (interceptors.hasNext()) {

final InterceptorMapping interceptor = (InterceptorMapping) interceptors.next();

String interceptorMsg = \"interceptor: \" + interceptor.getName();

UtilTimerStack.push(interceptorMsg); try {

//执行栈中的(大约有15个左右)包扩参数封装,最后一个是捃行Action中的方法

resultCode =

interceptor.getInterceptor().intercept(DefaultActionInvocation.this); } finally {

UtilTimerStack.pop(interceptorMsg); } } else {

resultCode = invokeActionOnly(); }

// this is needed because the result will be executed, then control will return to the Interceptor, which will // return above and flow through again if (!executed) {

//查看是否配置了返回前监听事件,用户可以自己写事件,但要实理preResultListeners接口

if (preResultListeners != null) {

for (Object preResultListener : preResultListeners) { PreResultListener listener = (PreResultListener) preResultListener;

String _profileKey = \"preResultListener: \"; try {

UtilTimerStack.push(_profileKey);

listener.beforeResult(this, resultCode); }

finally {

UtilTimerStack.pop(_profileKey); } } }

// now execute the result, if we're supposed to

if (proxy.getExecuteResult()) { //执行返回 方法 executeResult(); }

executed = true; }

return resultCode; }

finally {

UtilTimerStack.pop(profileKey); }

}

//执行返回方法

private void executeResult() throws Exception { //创建返回对象,跟据不同的type创建不用的对象 result = createResult();

String timerKey = \"executeResult: \" + getResultCode(); try {

UtilTimerStack.push(timerKey); if (result != null) { //执行方法

result.execute(this); } else if (resultCode != null && !Action.NONE.equals(resultCode)) {

throw new ConfigurationException(\"No result defined for action \" + getAction().getClass().getName()

+ \" and result \" + getResultCode(), proxy.getConfig()); } else {

if (LOG.isDebugEnabled()) {

LOG.debug(\"No result returned for action \" + getAction().getClass().getName() + \" at \" + proxy.getConfig().getLocation()); } }

} finally {

UtilTimerStack.pop(timerKey); }

}

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- cepb.cn 版权所有 湘ICP备2022005869号-7

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务