tomcat《一》
验证:Tomcat猜想 是不是由一个个Socket组装的Servlet
*/
protected class Acceptor extends AbstractEndpoint.Acceptor {
@Override
public void run() {
int errorDelay = 0;
// Loop until we receive a shutdown command
while (running) {//判断云运行状态
// Loop if endpoint is paused
while (paused && running) {
state = AcceptorState.PAUSED;
try {
Thread.sleep(50);
} catch (InterruptedException e) {
// Ignore
}
}
if (!running) {
break;
}
state = AcceptorState.RUNNING;
try {
//if we have reached max connections, wait
countUpOrAwaitConnection();
Socket socket = null;
try {
// Accept the next incoming connection from the server
// socket 一个工厂循环创建socket
socket = serverSocketFactory.acceptSocket(serverSocket);
} catch (IOException ioe) {
countDownConnection();
// Introduce delay if necessary
errorDelay = handleExceptionWithDelay(errorDelay);
// re-throw
throw ioe;
}
// Successful accept, reset the error delay
errorDelay = 0;
// Configure the socket
if (running && !paused && setSocketOptions(socket)) {
// Hand this socket off to an appropriate processor
if (!processSocket(socket)) {
countDownConnection();
// Close socket right away
closeSocket(socket);
}
} else {
countDownConnection();
// Close socket right away
closeSocket(socket);
}
} catch (IOException x) {
if (running) {
log.error(sm.getString("endpoint.accept.fail"), x);
}
} catch (NullPointerException npe) {
if (running) {
log.error(sm.getString("endpoint.accept.fail"), npe);
}
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString("endpoint.accept.fail"), t);
}
}
state = AcceptorState.ENDED;
}
}
public class DefaultServerSocketFactory implements ServerSocketFactory { @Override public ServerSocket createSocket (int port) throws IOException { return new ServerSocket (port); } @Override public ServerSocket createSocket (int port, int backlog) throws IOException { return new ServerSocket (port, backlog); } @Override public ServerSocket createSocket (int port, int backlog, InetAddress ifAddress) throws IOException { return new ServerSocket (port, backlog, ifAddress); } ......
Tomcat架构猜想,server.xml中每一个标签对应一个类,
接下来先分析Contex到官网发现:
The Context element represents a web application,
which is run within a particular virtual host.
Each web application is based on a Web Application Archive (WAR) file,
or a corresponding directory containing the corresponding unpacked contents
第一句可以发现一个Contetx就是一个web项目。
那么疑问来了,web是不是把一个个Servlet进行组装呢?
源码: public class StandardContext extends ContainerBase implements Context, NotificationEmitter StandardContext 实现了Context重写的方法如下 public boolean loadOnStartup(Container[] children) { TreeMap<Integer, ArrayList<Wrapper>> map = new TreeMap(); for(int i = 0; i < children.length; ++i) { Wrapper wrapper = (Wrapper)children[i]; int loadOnStartup = wrapper.getLoadOnStartup(); if (loadOnStartup >= 0) { Integer key = loadOnStartup; ArrayList<Wrapper> list = (ArrayList)map.get(key); if (list == null) { list = new ArrayList(); map.put(key, list); } list.add(wrapper); } }
Conetxt添加了servlet,但是StandContext里这个方法加载的是Wrapper.接下来看Wrapper是否是等于Servlet,源码中使用了包装器模式进行了加强
ContextConfig类的854行左右的这个方法
configureContext在990行左右的源码
while(var31.hasNext()) {
ServletDef servlet = (ServletDef)var31.next();
//使用包装器的方法
Wrapper wrapper = this.context.createWrapper();
//使用包装器的方法把Servlet与Wrapper进行转化
if (servlet.getLoadOnStartup() != null) {
wrapper.setLoadOnStartup(servlet.getLoadOnStartup());
}
if (servlet.getEnabled() != null) {
//使用包装器的方法把Servlet与Wrapper进行转化
wrapper.setEnabled(servlet.getEnabled());
}
//使用包装器的方法把Servlet与Wrapper进行转化
wrapper.setName(servlet.getServletName());
Map<String, String> params = servlet.getParameterMap();
var7 = params.entrySet().iterator();
while(var7.hasNext()) {
Entry<String, String> entry = (Entry)var7.next();
//使用包装器的方法把Servlet与Wrapper进行转化
wrapper.addInitParameter((String)entry.getKey(), (String)entry.getValue());
}
wrapper.setRunAs(servlet.getRunAs());
Set<SecurityRoleRef> roleRefs = servlet.getSecurityRoleRefs();
Iterator var33 = roleRefs.iterator();
while(var33.hasNext()) {
SecurityRoleRef roleRef = (SecurityRoleRef)var33.next();
wrapper.addSecurityReference(roleRef.getName(), roleRef.getLink());
}
//使用包装器的方法把Servlet与Wrapper进行转化
wrapper.setServletClass(servlet.getServletClass());
MultipartDef multipartdef = servlet.getMultipartDef();
if (multipartdef != null) {
if (multipartdef.getMaxFileSize() != null && multipartdef.getMaxRequestSize() != null && multipartdef.getFileSizeThreshold() != null) {
wrapper.setMultipartConfigElement(new MultipartConfigElement(multipartdef.getLocation(), Long.parseLong(multipartdef.getMaxFileSize()), Long.parseLong(multipartdef.getMaxRequestSize()), Integer.parseInt(multipartdef.getFileSizeThreshold())));
} else {
wrapper.setMultipartConfigElement(new MultipartConfigElement(multipartdef.getLocation()));
}
}
if (servlet.getAsyncSupported() != null) {
//使用包装器的方法把Servlet与Wrapper进行转化
wrapper.setAsyncSupported(servlet.getAsyncSupported());
}
//使用包装器的方法把Servlet与Wrapper进行转化
wrapper.setOverridable(servlet.isOverridable());
//使用包装器的方法把Servlet与Wrapper进行转化 最终添加
this.context.addChild(wrapper);
}
一点点学习,一丝丝进步。不懈怠,才不会被时代淘汰