嗯,又好久没写了,WebServer的项目也好久没更新代码了,下周要考软件测试了,复习之前抽点空再写一点,以免时间太久都忘记写的内容了。今天主要是完成对Server的配置和Server的实例化。
Server的配置包括Server的实现类,配置Server的监听器,控制端口,Server下有哪些Service,所谓Service,就是Tomcat提供哪些服务,比如用于Servlet的服务,或者WebSocket的服务,一个Service把一个Connector与一个Container联系起来,请求经过Connector的解析后交由Container进行业务逻辑处理,然后返回结果,最后由Connector返回给前端请求者,最后就是Context,一个Context表示一个Web Application,说简单点就是一个网站。
<?xml version="1.0" encoding="utf-8" ?> <server> <impl>com.benson.webserver.server.DefaultServer</impl> <port>8000</port> <listeners> <listener class="com.benson.webserver.server.listener.ServerLogListener"/> </listeners> <services> <service name="httpService" class="com.benson.webserver.core.service.HttpStandardService"> <connector class="com.benson.webserver.connector." port="8888" protocol="HTTP/1.1" connectTimeout="20000"/> <container class="com.benson.webserver.container.StandardHost"/> </service> </services> <context> <basePath>/aa</basePath> <path>/test</path> <reloadable>false</reloadable> </context> </server>
配置文件大概就是这个样子
Server在实例化之前就会读取配置文件,然后生成Config对象,并把Config对应注入到Server对象中,然后再依次实例化其他组件。
读取配置的配置加载器
package com.benson.webserver.server.config; import com.benson.webserver.classloader.CoreClassLoader; import com.benson.webserver.config.ConfigLoader; import com.benson.webserver.config.ContextConfig; import com.benson.webserver.connector.Connector; import com.benson.webserver.container.Container; import com.benson.webserver.core.service.Service; import com.benson.webserver.core.service.config.ServiceConfig; import com.benson.webserver.exception.ConfigLoadException; import com.benson.webserver.server.Server; import com.benson.webserver.util.BeanFactory; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import java.io.File; import java.util.ArrayList; import java.util.List; import static com.benson.webserver.core.Bootstrap.RESOURCES_PATH; /** * 服务器配置加载器 * author benson * time 2017/12/15 上午11:23 * email 1455813736@qq.com */ public class ServerConfigLoader implements ConfigLoader<ServerConfig> { @Override public ServerConfig load() throws ConfigLoadException { CoreClassLoader classLoader = BeanFactory.getBean(CoreClassLoader.class); String serverClassStr; ServerConfig config = new ServerConfig(); SAXReader reader = new SAXReader(); try { //读出server和listener节点 Document document = reader.read(new File(RESOURCES_PATH+"server_config.xml")); Element serverEle = document.getRootElement(); Element implEle = serverEle.element("impl"); //读取Server实现类 serverClassStr = implEle.getTextTrim(); Class<? extends Server> serverClass = (Class<? extends Server>) classLoader.loadClass(serverClassStr);//这里使用自定义的类加载器,保护Server的安全同时也保证了WebServer系统与WebApp之间的低耦合性 config.setServerClass(serverClass); //读取控制端口 Element portEle = serverEle.element("port"); int prot = Integer.parseInt(portEle.getTextTrim()); config.setPort(prot); //读取listener配置 Element listenersEle = serverEle.element("listeners"); List<Element> listenerEles = listenersEle.elements(); config.setListenerClass(new ArrayList()); for(Element e:listenerEles){ String listenerClassStr = e.attributeValue("class"); Class listenerClass = classLoader.loadClass(listenerClassStr); config.getListenerClass().add(listenerClass); } //读取service配置 Element servicesEle = serverEle.element("services"); List<Element> serviceEles = servicesEle.elements(); config.setServiceConfigs(new ArrayList()); for(Element e:serviceEles){ String name = e.attributeValue("name"); String classStr = e.attributeValue("class"); ServiceConfig serviceConfig = new ServiceConfig(); serviceConfig.setName(name); serviceConfig.setServiceClass((Class<? extends Service>) classLoader.loadClass(classStr)); List<Element> connectorEles = e.elements("connector"); serviceConfig.setConnectors(new ArrayList()); for(Element connectorEle:connectorEles){ Class<?> connectorClass = classLoader.loadClass(connectorEle.attributeValue("class")); Connector connector = (Connector) connectorClass.newInstance(); connector.setPort(Integer.parseInt(connectorEle.attributeValue("port"))); connector.setProtocol(connectorEle.attributeValue("protocol")); connector.setConnectTimeout(Long.parseLong(connectorEle.attributeValue("connectTimeout"))); serviceConfig.getConnectors().add(connector); } Element containerEle = e.element("container"); Class<? extends Container> containerClass = (Class<? extends Container>) classLoader.loadClass(containerEle.attributeValue("class")); serviceConfig.setContainerClass(containerClass); config.getServiceConfigs().add(serviceConfig); } //读取应用上下文列表 List<Element> contextEles = serverEle.elements("context"); config.setContextConfigs(new ArrayList()); for(Element contextEle:contextEles){ ContextConfig contextConfig = new ContextConfig(); Element basePathEle = contextEle.element("basePath"); contextConfig.setBasePath(basePathEle.getTextTrim()); Element pathEle = contextEle.element("path"); contextConfig.setPath(pathEle.getTextTrim()); Element reloadableEle = contextEle.element("reloadable"); contextConfig.setReloadable(Boolean.parseBoolean(reloadableEle.getTextTrim())); config.getContextConfigs().add(contextConfig); } }catch (RuntimeException re){ re.printStackTrace(); }catch (DocumentException de) { de.printStackTrace(); }catch (ClassNotFoundException cnfe) { cnfe.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } return config; } }