StandardServer类:
该类的签名如下:
public final class StandardServer implements Lifecycle, Server, MBeanRegistration
该类实现了Lifecycle, Server, MBeanRegistration接口。
Lifecycle接口是Catalina的组件的通用声明周期方法的接口,组件可以选择实现该接口。该接口定义了声明周期统一启动停止机制。方法定义如下:
void |
addLifecycleListener(LifecycleListener listener) Add a LifecycleEvent listener to this component. |
LifecycleListener[] |
findLifecycleListeners() Get the lifecycle listeners associated with this lifecycle. |
void |
removeLifecycleListener(LifecycleListener listener) Remove a LifecycleEvent listener from this component. |
void |
start() Prepare for the beginning of active use of the public methods of this component. |
void |
stop() Gracefully terminate the active use of the public methods of this component. |
另外,还是用静态变量定义了一些常量:
如:
/**
* The LifecycleEvent type for the "component init" event.
*/
public static final String INIT_EVENT = "init";
Server接口表示整个Catalina servlet容器,它的属性代表了整个servlet容器的属性,一个Server可以有多个service,以及顶层命名资源集。
该接口的实现要在指定端口上建立一个Server socket,是用其来监测连接,收到连接后首先需要跟关闭指令进行比较,如果是关闭指令则关闭服务。否则继续服务。
MBeanRegistration 接口:
该接口表示可以由 MBean 实现,以便在向 MBean 服务器注册或从其注销之前和之后执行操作。
void |
postDeregister() 允许 MBean 在已从 MBean 服务器注销之后执行所需要的任何操作。 |
void |
postRegister(Boolean registrationDone) 允许 MBean 在被注册到 MBean 服务器或注销失败后执行任何所需要的操作。 |
void |
preDeregister() 允许该 MBean 在从 MBean 服务器注销之前执行它所需要的任何操作。 |
ObjectName |
preRegister(MBeanServer server, ObjectName name) 允许 MBean 在被注册到 MBean 服务器之前执行它所需要的任何操作。 |
构造函数如下:
public StandardServer() {
super();
ServerFactory.setServer(this);//设置ServerFactory里的Server对象
globalNamingResources = new NamingResources();//命名资源,这个类后面再看~~
globalNamingResources.setContainer(this);//设置命名资源的容器
if (isUseNaming()) {
if (namingContextListener == null) {
namingContextListener = new NamingContextListener();
addLifecycleListener(namingContextListener);
}
}
}
addService方法
public void addService(Service service) {
service.setServer(this);
synchronized (services) {
Service results[] = new Service[services.length + 1];
System.arraycopy(services, 0, results, 0, services.length);
results[services.length] = service;
services = results;
if (initialized) {
try {
service.initialize();
} catch (LifecycleException e) {
log.error(e);
}
}
if (started && (service instanceof Lifecycle)) {
try {
((Lifecycle) service).start();
} catch (LifecycleException e) {
;
}
}
// Report this property change to interested listeners
support.firePropertyChange("service", null, service);
}
}
这个方法的实现个人认为不太好,我尝试将其改为如下内容:
List<Service>servList=Arrays.asList(services);
servList.add(service);
services=servList.toArray(new Service[0]);
修改1:等整个修改完后会测试下修改后的性能
await方法:
public void await() {
// Negative values - don't wait on port - tomcat is embedded or we just don't like ports
if( port == -2 ) {
// undocumented yet - for embedding apps that are around, alive.
return;
}
if( port==-1 ) {
while( true ) {
try {
Thread.sleep( 10000 );
} catch( InterruptedException ex ) {
}
if( stopAwait ) return;
}
}
// Set up a server socket to wait on
ServerSocket serverSocket = null;
try {
serverSocket =
new ServerSocket(port, 1,
InetAddress.getByName("localhost"));
} catch (IOException e) {
log.error("StandardServer.await: create[" + port
+ "]: ", e);
System.exit(1);
}
// Loop waiting for a connection and a valid command
while (true) {
// Wait for the next connection
Socket socket = null;
InputStream stream = null;
try {
socket = serverSocket.accept();
socket.setSoTimeout(10 * 1000); // Ten seconds
stream = socket.getInputStream();
} catch (AccessControlException ace) {
log.warn("StandardServer.accept security exception: "
+ ace.getMessage(), ace);
continue;
} catch (IOException e) {
log.error("StandardServer.await: accept: ", e);
System.exit(1);
}
// Read a set of characters from the socket
StringBuffer command = new StringBuffer();
int expected = 1024; // Cut off to avoid DoS attack
while (expected < shutdown.length()) {
if (random == null)
random = new Random();
expected += (random.nextInt() % 1024);
}
while (expected > 0) {
int ch = -1;
try {
ch = stream.read();
} catch (IOException e) {
log.warn("StandardServer.await: read: ", e);
ch = -1;
}
if (ch < 32) // Control character or EOF terminates loop
break;
command.append((char) ch);
expected--;
}
// Close the socket now that we are done with it
try {
socket.close();
} catch (IOException e) {
;
}
// Match against our command string
boolean match = command.toString().equals(shutdown);
if (match) {
break;
} else
log.warn("StandardServer.await: Invalid command '" +
command.toString() + "' received");
}
// Close the server socket and return
try {
serverSocket.close();
} catch (IOException e) {
;
}
}
这段代码会创建一个ServerSocket,绑定到8005端口上,然后进入一个循环,在循环中会一直接受连接,直到收到关闭命令的时候,跳出循环,执行serverSocket.close()方法关闭服务器。
public void removeService(Service service) {
synchronized (services) {
int j = -1;
for (int i = 0; i < services.length; i++) {
if (service == services[i]) {
j = i;
break;
}
}
if (j < 0)
return;
if (services[j] instanceof Lifecycle) {
try {
((Lifecycle) services[j]).stop();
} catch (LifecycleException e) {
;
}
}
int k = 0;
Service results[] = new Service[services.length - 1];
for (int i = 0; i < services.length; i++) {
if (i != j)
results[k++] = services[i];
}
services = results;
// Report this property change to interested listeners
support.firePropertyChange("service", service, null);
}
}
这段代码实现的还是不错的~~~~...第二天我改变主意了,这段代码太复杂,可以简化下,我在standardService中进行修改,这里暂且不改了
stop方法:
public void stop() throws LifecycleException {
// Validate and update our current component state
if (!started)
return;
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT, null);
lifecycle.fireLifecycleEvent(STOP_EVENT, null);
started = false;
// Stop our defined Services
for (int i = 0; i < services.length; i++) {
if (services[i] instanceof Lifecycle)
((Lifecycle) services[i]).stop();
}
// Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT, null);
if (port == -1)
stopAwait();
}
private LifecycleSupport lifecycle = new LifecycleSupport(this);
这是负责生命周期的属性~~