[Tomcat6.0源码]Servlet API之ServletConfig、ServletContext
来源:互联网 发布:在党规党纪面前知敬畏 编辑:程序博客网 时间:2024/05/18 05:56
我们编写Servlet类的时候,都继承自HttpServlet。而HttpServlet又继承了GenericServlet类,实现了Servlet、ServletConfig接口。
(图片来自http://getmc.blog.bokee.net/bloggermodule/blog_viewblog.do?id=57343)
在写doPost()、doGet()的时候,ServletConfig、ServletContext等内置对象比较常用:
1.GenericServlet.getServletConfig()返回ServletConfig对象:
public ServletConfig getServletConfig() {return config; }
而这个config是Servlet初始化时候设置的,StandardWrapper.loadServlet():
servlet.init(facade);
这个facade是在StandardWrapper属性中new出来的:
protected StandardWrapperFacade facade = new StandardWrapperFacade(this);
StandardWrapperFacade是实现了ServletConfig接口。它是对StandardWrapper类的封装:
public final class StandardWrapperFacade implements ServletConfig { // ----------------------------------------------------------- Constructors /** * Create a new facede around a StandardWrapper. */ public StandardWrapperFacade(StandardWrapper config) { super(); this.config = (ServletConfig) config; } // ----------------------------------------------------- Instance Variables /** * Wrapped config. */ private ServletConfig config = null; /** * Wrapped context (facade). */ private ServletContext context = null; // -------------------------------------------------- ServletConfig Methods public String getServletName() { return config.getServletName(); } public ServletContext getServletContext() { if (context == null) { context = config.getServletContext(); if ((context != null) && (context instanceof ApplicationContext)) context = ((ApplicationContext) context).getFacade(); } return (context); } public String getInitParameter(String name) { return config.getInitParameter(name); } public Enumeration getInitParameterNames() { return config.getInitParameterNames(); }}
StandardWrapper的属性方法很多,有些是不能让tomcat用户直接访问的。而有些是可以对他们开放的。所以就有了这么个Facade。
getInitParameter()调用的是StandardWrapper.getInitParameter():
public String getInitParameter(String name) { return (findInitParameter(name)); }
StandardWrapper.findInitParameter():
public String findInitParameter(String name) { try { parametersLock.readLock().lock(); return ((String) parameters.get(name)); } finally { parametersLock.readLock().unlock(); } }
StandardWrapper.parameters是HashMap类型,来自StandardWrapper.addInitParameter():
public void addInitParameter(String name, String value) { try { parametersLock.writeLock().lock(); parameters.put(name, value); } finally { parametersLock.writeLock().unlock(); } fireContainerEvent("addInitParameter", name); }
这个方法的调用是在StandardContext解析web.xml的时候(WebRuleSet里配置的)
digester.addCallMethod(prefix + "web-app/filter/init-param", "addInitParameter", 2); digester.addCallParam(prefix + "web-app/filter/init-param/param-name", 0); digester.addCallParam(prefix + "web-app/filter/init-param/param-value", 1);
另外,结构图中有两个方法:GenericServlet.getInitParameter(),调用的还是StandardWrapperFacade.getInitParameter();
public String getInitParameter(String name) {return getServletConfig().getInitParameter(name); }
GenericServlet.getInitParameterNames()调用的是StandardWrapperFacade.getInitParameterNames()。
2.ServletContext来自GenericServlet.getServletContext(),调用的是StandardWrapperFacade.getServletContext():
public ServletContext getServletContext() { if (context == null) { context = config.getServletContext(); if ((context != null) && (context instanceof ApplicationContext)) context = ((ApplicationContext) context).getFacade(); } return (context); }
StandardWrapperFacade中的config是StandardWrapper对象。将调用StandardWrapper.getServletContext():
public ServletContext getServletContext() { if (parent == null) return (null); else if (!(parent instanceof Context)) return (null); else return (((Context) parent).getServletContext()); }
StandardContext.getServletContext():
public ServletContext getServletContext() { if (context == null) { context = new ApplicationContext(getBasePath(), this); if (altDDName != null) context.setAttribute(Globals.ALT_DD_ATTR,altDDName); } return (context.getFacade()); }
context.getFacade()即ApplicationContext.getFacade():
protected ServletContext getFacade() { return (this.facade); }
facade来自ApplicationContext的属性:
private ServletContext facade = new ApplicationContextFacade(this);
ServletContext有个方法getInitParameter():
public String getInitParameter(String name) { if (SecurityUtil.isPackageProtectionEnabled()) { return (String) doPrivileged("getInitParameter", new Object[]{name}); } else { return context.getInitParameter(name); } }context.getInitParameter()调用的是ApplicationContext.getInitParameter():
public String getInitParameter(final String name) { return parameters.get(name); }
parameters是ConcurrentHashMap类型的对象,在ApplicationContext属性中new出来的,往里边设值是用setInitParameter()方法:
public boolean setInitParameter(String name, String value) { if (parameters.containsKey(name)) { return false; } parameters.put(name, value); return true; }里边的值是StandardContext.start()时调用mergeParameters()方法,逐个往里边放值:
private void mergeParameters() { Map<String,String> mergedParams = new HashMap<String,String>(); String names[] = findParameters(); for (int i = 0; i < names.length; i++) { mergedParams.put(names[i], findParameter(names[i])); } ApplicationParameter params[] = findApplicationParameters(); for (int i = 0; i < params.length; i++) { if (params[i].getOverride()) { if (mergedParams.get(params[i].getName()) == null) { mergedParams.put(params[i].getName(), params[i].getValue()); } } else { mergedParams.put(params[i].getName(), params[i].getValue()); } } for (Map.Entry<String,String> entry : mergedParams.entrySet()) { context.setInitParameter(entry.getKey(), entry.getValue()); } }findParameters()是将HashMap类型的parameters转成String数组。parameters是来自WebRuleSet中配置的规则:
digester.addCallMethod(prefix + "web-app/context-param", "addParameter", 2); digester.addCallParam(prefix + "web-app/context-param/param-name", 0); digester.addCallParam(prefix + "web-app/context-param/param-value", 1);findApplicationParameters()返回的是ApplicationParameter类型的数组applicationParameters。applicationParameters来自Catalina解析server.xml
digester.addRuleSet(new ContextRuleSet("Server/Service/Engine/Host/"));ContextRuleSet:
digester.addObjectCreate(prefix + "Context/Parameter", "org.apache.catalina.deploy.ApplicationParameter"); digester.addSetProperties(prefix + "Context/Parameter"); digester.addSetNext(prefix + "Context/Parameter", "addApplicationParameter", "org.apache.catalina.deploy.ApplicationParameter");
捋捋:
ServletConfig和ServletContext对象都有setAttribute和getAttribute方法。
论作用域,ServletConfig是封装了一些StandardWrapper方法的StandardWrapperFacade对象,StandardWrapper又是对servlet的封装。所以保存ServletConfig中的参数,在在该servlet生命周期内有用,其他servlet访问不到这里的数据。
ServletContext是ApplicationContextFacade对象,他是对ApplicationContext的封装,而ApplicationContext又是对StandardContext的封装。同一个应用的servlet都可以访问这个ServletContext的参数。
另外,Servlet API只是一个规范,相关的方法名及实现的功能是大家定的,而里边具体怎么实现,就由个个厂家自己发挥了。jboss、weblogic、tomcat实现方式可能不同,但都遵守那些规范。
- [Tomcat6.0源码]Servlet API之ServletConfig、ServletContext
- [Tomcat6.0源码]Servlet API之Request
- Servlet之ServletConfig和ServletContext
- [Tomcat6.0源码]Servlet API之Session、Cookie
- Servlet之ServletConfig和ServletContext的探索
- Servlet之request请求、ServletContext、ServletConfig
- Servlet之ServletConfig与ServletContext对象
- Servlet容器模型之ServletConfig、ServletContext
- Servlet API 之ServletContext
- Servlet注意+ServletConfig+ServletContext
- Servlet、servletConfig、ServletContext简介
- 【Servlet】ServletConfig和ServletContext
- Servlet—ServletConfig、ServletContext
- Servlet、ServletConfig和ServletContext
- Servlet总结-ServletConfig、ServletContext
- Servlet之旅-ServletConfig与ServletContext的区别
- JavaWeb 之 servletConfig,servletContext
- servlet-01 servletConfig和servletContext
- 开博开篇
- SqliteDatabase insert(String table, String nullColumnHack, ContentValues values)
- 对一个正整数作如下操作:如果是偶数则除以2,如果是奇数则加1,如此进行直到1时操作停止,求经过9次操作变为1的数有多少个?
- Qt 坐标系统 笔记
- 嵌入式Linux之我行——S3C2440上MMC/SD卡驱动实例开发讲解(一)
- [Tomcat6.0源码]Servlet API之ServletConfig、ServletContext
- 字符串函数
- QSettings 自定义格式
- Qt查看主机信息如ip/hardware address/netmask等
- python操作Excel word
- GEF基础入门(2)-GEF MVC介绍
- C++_运算符重载
- Java多线程的创建和启动
- c++链接access