一步步实现WebServer中间件——Server的配置读取与实例化

嗯,又好久没写了,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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值