设为首页 收藏本站
查看: 450|回复: 0

[经验分享] tomcat源码学习--轰炸机core(一)

[复制链接]

尚未签到

发表于 2017-1-31 08:12:56 | 显示全部楼层 |阅读模式
前言:
    catalina下面的core包,包含了很多我们平时一直使用到的东西,以前一直用不知道原理,也只知道j2EE api里面的东西,在tomcat下写了这么久得程序,一直疑惑它到底是怎么做到的,下面就可以好好看看了。
    首先application,实现javax.servlet Interface ServletContext
引用

Defines a set of methods that a servlet uses to communicate with its servlet container, for example, to get the MIME type of a file, dispatch requests, or write to a log file.
There is one context per "web application" per Java Virtual Machine. (A "web application" is a collection of servlets and content installed under a specific subset of the server's URL namespace such as /catalog and possibly installed via a .war file.)
In the case of a web application marked "distributed" in its deployment descriptor, there will be one context instance for each virtual machine. In this situation, the context cannot be used as a location to share global information (because the information won't be truly global). Use an external resource like a database instead.
The ServletContext object is contained within the ServletConfig object, which the Web server provides the servlet when the servlet is initialized.


    这家伙很重要,那么每个容器必须自己实现他的规则,tomcat如何实现呢?
eclipse果断查找
DSC0000.jpg
    ApplicationContextFacade是为ApplicationContext服务的一个类,ApplicationContext才是标准实现了这个借口的类,至于JspCServletContext是Simple ServletContext
  那么就重点看ApplicationContext,有的属性如下
DSC0001.jpg
构造方法如下:
引用

  /**
     * Construct a new instance of this class, associated with the specified
     * Context instance.
     *
     * @param context The associated Context instance
     */
    public ApplicationContext(String basePath, StandardContext context) {
        super();
        this.context = context;
        this.basePath = basePath;
    }


    里面的StandardContext是实现标准Context借口的类,这个上下文借口是tomcat自己定义的,里面涉及到tomcat容器的众多处理,并且他还是个集成Container借口的接口,这么看来这个StandardContext是相当强大,当然没有这么一个强大的处理类注入,并且这个注入的类也需要从从操作里面反馈给自己很多东西
    具体看里面的方法,经常用到的属性值set/getAttribute(String) ,重点看set,能解决很多以前的疑惑,里面的层层判断说明不是自己想得那样就是map里面put,它有自己的策略,没次还要去看readOnlyAttributes里面是否有这个key,有就不能移除。
public void setAttribute(String name, Object value) {
// Name cannot be null
if (name == null)
throw new IllegalArgumentException
(sm.getString("applicationContext.setAttribute.namenull"));
// Null value is the same as removeAttribute()
if (value == null) {
removeAttribute(name);
return;
}
Object oldValue = null;
boolean replaced = false;
// Add or replace the specified attribute
// Check for read only attribute
if (readOnlyAttributes.containsKey(name))
return;
oldValue = attributes.get(name);
if (oldValue != null)
replaced = true;
attributes.put(name, value);
// Notify interested application event listeners
Object listeners[] = context.getApplicationEventListeners();
if ((listeners == null) || (listeners.length == 0))
return;
ServletContextAttributeEvent event = null;
if (replaced)
event =
new ServletContextAttributeEvent(context.getServletContext(),
name, oldValue);
else
event =
new ServletContextAttributeEvent(context.getServletContext(),
name, value);
for (int i = 0; i < listeners.length; i++) {
if (!(listeners instanceof ServletContextAttributeListener))
continue;
ServletContextAttributeListener listener =
(ServletContextAttributeListener) listeners;
try {
if (replaced) {
context.fireContainerEvent
("beforeContextAttributeReplaced", listener);
listener.attributeReplaced(event);
context.fireContainerEvent("afterContextAttributeReplaced",
listener);
} else {
context.fireContainerEvent("beforeContextAttributeAdded",
listener);
listener.attributeAdded(event);
context.fireContainerEvent("afterContextAttributeAdded",
listener);
}
} catch (Throwable t) {
if (replaced)
context.fireContainerEvent("afterContextAttributeReplaced",
listener);
else
context.fireContainerEvent("afterContextAttributeAdded",
listener);
// FIXME - should we do anything besides log these?
log(sm.getString("applicationContext.attributeEvent"), t);
}
}
}

    容器里面使用的是哪一个呢?我们并不知道,我们完全是面对借口来编程,遵循j2ee api规范,然后具体的方法具体的容器有自己的实现。
     同样下面还有req reps,分别有两个实现,比如继承自HttpServletRequestWrapper或者ServletRequestWrapper的两个类,还来了句这个,顶层都是ServletRequest
引用

WARNING</strong>:  Due to Java's lack of support for multiple
* inheritance, all of the logic in <code>ApplicationRequest</code> is
* duplicated in <code>ApplicationHttpRequest</code>.  Make sure that you
* keep these two classes in synchronization when making changes!


   我比较关注session,里面还是一些session的策略,如果怎样变怎样,session为了安全只有一份,原来这两个getSession(),getSession(boolean create)是这么个关系,以前都挺纠结的

/**
* Return the session associated with this Request, creating one
* if necessary.
*/
public HttpSession getSession() {
return (getSession(true));
}
/**
* Return the session associated with this Request, creating one
* if necessary and requested.
*
* @param create Create a new session if one does not exist
*/
public HttpSession getSession(boolean create) {
if (crossContext) {
// There cannot be a session if no context has been assigned yet
if (context == null)
return (null);
// Return the current session if it exists and is valid
if (session != null && session.isValid()) {
return (session.getSession());
}
HttpSession other = super.getSession(false);
if (create && (other == null)) {
// First create a session in the first context: the problem is
// that the top level request is the only one which can
// create the cookie safely
other = super.getSession(true);
}
if (other != null) {
Session localSession = null;
try {
localSession =
context.getManager().findSession(other.getId());
if (localSession != null && !localSession.isValid()) {
localSession = null;
}
} catch (IOException e) {
// Ignore
}
if (localSession == null && create) {
localSession =
context.getManager().createSession(other.getId());
}
if (localSession != null) {
localSession.access();
session = localSession;
return session.getSession();
}
}
return null;
} else {
return super.getSession(create);
}
}

    好累啊,看不动了,下次重点看下面的几个复杂的容器类ContainerBase Lifecycle

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-335533-1-1.html 上篇帖子: 关于Jboss/Tomcat/Jetty的JNDI定义 下篇帖子: Tomcat中简易定时器的实现
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表