[Tomcat6.0源码]Servlet API之ServletConfig、ServletContext
2012-10-09 22:50
351 查看
我们编写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对象:
而这个config是Servlet初始化时候设置的,StandardWrapper.loadServlet():
这个facade是在StandardWrapper属性中new出来的:
StandardWrapperFacade是实现了ServletConfig接口。它是对StandardWrapper类的封装:
StandardWrapper的属性方法很多,有些是不能让tomcat用户直接访问的。而有些是可以对他们开放的。所以就有了这么个Facade。
getInitParameter()调用的是StandardWrapper.getInitParameter():
StandardWrapper.findInitParameter():
StandardWrapper.parameters是HashMap类型,来自StandardWrapper.addInitParameter():
这个方法的调用是在StandardContext解析web.xml的时候(WebRuleSet里配置的)
另外,结构图中有两个方法:GenericServlet.getInitParameter(),调用的还是StandardWrapperFacade.getInitParameter();
GenericServlet.getInitParameterNames()调用的是StandardWrapperFacade.getInitParameterNames()。
2.ServletContext来自GenericServlet.getServletContext(),调用的是StandardWrapperFacade.getServletContext():
StandardWrapperFacade中的config是StandardWrapper对象。将调用StandardWrapper.getServletContext():
StandardContext.getServletContext():
context.getFacade()即ApplicationContext.getFacade():
facade来自ApplicationContext的属性:
ServletContext有个方法getInitParameter():
parameters是ConcurrentHashMap类型的对象,在ApplicationContext属性中new出来的,往里边设值是用setInitParameter()方法:
里边的值是StandardContext.start()时调用mergeParameters()方法,逐个往里边放值:
捋捋:
ServletConfig和ServletContext对象都有setAttribute和getAttribute方法。
论作用域,ServletConfig是封装了一些StandardWrapper方法的StandardWrapperFacade对象,StandardWrapper又是对servlet的封装。所以保存ServletConfig中的参数,在在该servlet生命周期内有用,其他servlet访问不到这里的数据。
ServletContext是ApplicationContextFacade对象,他是对ApplicationContext的封装,而ApplicationContext又是对StandardContext的封装。同一个应用的servlet都可以访问这个ServletContext的参数。
另外,Servlet API只是一个规范,相关的方法名及实现的功能是大家定的,而里边具体怎么实现,就由个个厂家自己发挥了。jboss、weblogic、tomcat实现方式可能不同,但都遵守那些规范。
(图片来自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之Session、Cookie
- [Tomcat6.0源码]Servlet API之Request
- 【JavaEE】Servlet接口、ServletConfig接口、GenericServlet抽象类、ServletContext接口、HttpServlet类源码及方法
- Servlet初始化参数(ServletConfig)与Servlet上下文初始化参数(ServletContext)区别
- Servlet、ServletConfig、ServletContext之间的关系!
- javaweb-day05-5&6&7(Servlet - ServletConfig对象 和 ServletContext对象)
- JavaWeb 初步学习一(ServletConfig参数获取,ServletContext共享数据与请求转发)
- Tomcat,Jstl,Servlet-api,jsp-api,standard各版本支持
- 对Servlet及tomcat关系的理解,以及Action与servletAPI的关系,以及httpServletRequest
- mvc-servlet---ServletConfig与ServletContext对象详解(转载)
- 深入Jetty源码之Servlet框架及实现(ServletContext)
- (24)ServletConfig和ServletContext
- Servlet第二篇【Servlet调用图、Servlet细节、ServletConfig、ServletContext】
- 对Servlet及tomcat关系的理解,以及Action与servletAPI的关系,以及httpServletRequest
- servlet.getServletContext()和getServletConfig(),什么意思和用法
- ServletConfig和ServletContext接口
- servletContext与servletConfig的区别
- [Tomcat6.0源码]请求的处理三Mapper、JMX
- Tomcat6.0源码学习--启动框架
- ServletConfig和ServletContext对象