【从零写javaweb框架】(二)定义和加载配置项

上一篇我们搭建了项目环境【从零写javaweb框架】(一)搭建开发环境,接下来要做的是定义和加载框架的配置项

第一步:定义配置项

打开上一篇创建好的demo1示例项目,在src/main/resources目录下创建一个smart.properties文件,内容如下:

#MySQL驱动
smart.framework.jdbc.driver=com.mysql.jdbc.Driver
#数据库url,不同数据库的url格式会有所不同,详情请百度
smart.framework.jdbc.url=jdbc:mysql://localhost:3306/demo
#数据库的账户名与密码
smart.framework.jdbc.username=root
smart.framework.jdbc.password=root


#demo1项目的基础包名
smart.framework.app.base_package=org.smart4j.demo1
#JSP的基础路径
smart.framework.app.jsp_path=/WEB-INF/view/
#静态资源文件的基础路径(如js、css、图片等)
smart.framework.app.asset_path=/asset/

第二步:加载配置项

现在已经有配置文件了,我们在这一步要做的是读取配置文件,首先写一个读取配置文件的工具类PropsUtil(注意:从这一步开始要切换到框架项目上进行):
package org.smart4j.framework.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * desc : 属性文件工具类
 * Created by Lon on 2018/1/21.
 */
public final class PropsUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(PropsUtil.class);

    /**
     * 加载属性文件
     */
    public static Properties loadProps(String fileName){
        Properties props = null;
        InputStream is = null;
        try {
            is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName);
            if (is == null){
                throw new FileNotFoundException(fileName + "file is not found");
            }
            props = new Properties();
            props.load(is);
        } catch (IOException e){
            LOGGER.error("load properties file failure", e);
        } finally {
            if (is != null){
                try {
                    is.close();
                } catch (IOException e){
                    LOGGER.error("close input stream failure", e);
                }
            }
        }
        return props;
    }

    /**
     * 获取字符型属性(默认值为空字符串)
     */
    public static String getString(Properties props, String key){
        return getString(props, key, "");
    }

    /**
     * 获取字符型属性(可指定默认值)
     */
    public static String getString(Properties props, String key, String defaultValue){
        String value = defaultValue;
        if (props.containsKey(key)){
            value = props.getProperty(key);
        }
        return value;
    }

    /**
     * 获取数值型属性(默认为0)
     */
    public static int getInt(Properties props, String key){
        return getInt(props, key, 0);
    }

    /**
     * 获取数值型属性(可指定默认值)
     */
    public static int getInt(Properties props, String key, int defaultValue){
        int value = defaultValue;
        if (props.containsKey(key)){
            value = CastUtil.castInt(props.getProperty(key));
        }
        return value;
    }

    /**
     * 获取布尔型属性(默认为false)
     */
    public static boolean getBoolean(Properties props, String key){
        return getBoolean(props, key, false);
    }

    /**
     * 获取布尔型属性(可指定默认值)
     */
    public static boolean getBoolean(Properties props, String key, boolean defaultValue){
        boolean value = defaultValue;
        if (props.containsKey(key)){
            value = CastUtil.castBoolean(props.getProperty(key));
        }
        return value;
    }

}

可以看到PropsUtil依赖了CastUtil这个工具类,这个类也需要我们来写,它的主要功能是类型转换:
package org.smart4j.framework.util;

/**
 * desc : 类型转换工具
 * Created by Lon on 2018/1/21.
 */
public final class CastUtil {

    /**
     * 转为String
     */
    public static String castString(Object obj){
        return CastUtil.castString(obj, "");
    }

    /**
     * 转为String(提供默认值)
     */
    public static String castString(Object obj, String defaultValue){
        return obj != null ? String.valueOf(obj) : defaultValue;
    }

    /**
     * 转为double
     */
    public static double castDouble(Object obj){
        return castDouble(obj, 0);
    }

    /**
     * 转为double(提供默认值)
     */
    public static double castDouble(Object obj, double defaultValue){
        double value = defaultValue;
        if (obj != null){
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)){
                try {
                    value = Double.parseDouble(strValue);
                } catch (NumberFormatException e){
                    value = defaultValue;
                }
            }
        }
        return value;
    }

    /**
     * 转为long
     */
    public static long castLong(Object obj){
        return castLong(obj, 0);
    }

    /**
     * 转为long(提供默认值)
     */
    public static long castLong(Object obj, long defaultValue){
        long value = defaultValue;
        if (obj != null){
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)){
                try {
                    value = Long.parseLong(strValue);
                } catch (NumberFormatException e){
                    value = defaultValue;
                }
            }
        }
        return value;
    }

    /**
     * 转为int
     */
    public static int castInt(Object obj){
        return castInt(obj, 0);
    }

    /**
     * 转为int(提供默认值)
     */
    public static int castInt(Object obj, int defaultValue){
        int value = defaultValue;
        if (obj != null){
            String strValue = castString(obj);
            if (StringUtil.isNotEmpty(strValue)){
                try {
                    value = Integer.parseInt(strValue);
                } catch (NumberFormatException e){
                    value = defaultValue;
                }
            }
        }
        return value;
    }

    /**
     * 转为boolean(提供默认值)
     */
    public static boolean castBoolean(Object obj){
        return castBoolean(obj, false);
    }

    /**
     * 转为boolean(提供默认值)
     */
    public static boolean castBoolean(Object obj, boolean defaultValue){
        boolean value = defaultValue;
        if (obj != null){
            value = Boolean.parseBoolean(castString(obj));
        }
        return value;
    }

}

CastUtil里面又用到了StringUtil,它是我们对commons-lang3中的StringUtils进一步封装:
package org.smart4j.framework.util;

import org.apache.commons.lang3.StringUtils;

/**
 * desc : 字符串工具
 * Created by Lon on 2018/1/21.
 */
public class StringUtil {

    /**
     * 判断字符串是否为空,这里会先去除字符串两端的空格再作判断
     */
    public static boolean isEmpty(String str){
        if (str != null){
            str = str.trim();
        }
        return StringUtils.isEmpty(str);
    }

    /**
     * 判断字符串是否为非空
     */
    public static boolean isNotEmpty(String str){
        return !isEmpty(str);
    }
    
}

顺便我们再把 commons-collections4的集合工具类也进一步封装(以后会用到的):

package org.smart4j.framework.util;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import java.util.Collection;
import java.util.Map;

/**
 * desc : 集合工具类
 * Created by Lon on 2018/1/21.
 */
public final class CollectionUtil {

    /**
     * 判断Collection是否为空
     */
    public static boolean isEmpty(Collection<?> collection){
        return CollectionUtils.isEmpty(collection);
    }

    /**
     * 判断Collection是否非空
     */
    public static boolean isNotEmpty(Collection<?> collection){
        return !isEmpty(collection);
    }

    /**
     * 判断Map是否为空
     */
    public static boolean isEmpty(Map<?, ?> map){
        return MapUtils.isEmpty(map);
    }

    /**
     * 判断Map是否非空
     */
    public static boolean isNotEmpty(Map<?, ?> map){
        return !MapUtils.isEmpty(map);
    }

}

到此,我们一口气写了4个工具类,这些类以后还会经常用到。

然后我们再次步入正题:如何读取smart.properties文件中的配置呢,现在需要先写一个ConfigConstant类来维护配置文件中各项配置的名称:

package org.smart4j.framework;

/**
 * desc : 框架配置常量
 * Created by Lon on 2018/1/21.
 */
public interface ConfigConstant {
    //对应配置文件名称
    String CONFIG_FILE = "smart.properties";
    //对应数据库连接配置项
    String JDBC_DRIVER = "smart.framework.jdbc.driver";
    String JDBC_URL = "smart.framework.jdbc.url";
    String JDBC_USERNAME = "smart.framework.jdbc.username";
    String JDBC_PASSWORD = "smart.framework.jdbc.password";
    //分别对应项目基础包名、JSP路径、静态资源基础路径
    String APP_BASE_PACKAGE = "smart.framework.app.base_package";
    String APP_JSP_PATH = "smart.framework.app.jsp_path";
    String APP_ASSET_PATH = "smart.framework.app.asset_path";

}

最后一步就是借助刚才写的PropsUtil工具类来实现ConfigHelper,其实就是通过定义一些静态方法让它有能力获取smart.properties中的配置项:

package org.smart4j.framework.helper;

import org.smart4j.framework.ConfigConstant;
import org.smart4j.framework.util.PropsUtil;

import java.util.Properties;

/**
 * desc : 属性文件助手类
 * Created by Lon on 2018/1/21.
 */
public final class ConfigHelper {

    private static final Properties CONFIG_PROPS = PropsUtil.loadProps(ConfigConstant.CONFIG_FILE);

    /**
     * 获取JDBC驱动
     */
    public static String getJdbcDriver(){
        return PropsUtil.getString(CONFIG_PROPS, ConfigConstant.JDBC_DRIVER);
    }

    /**
     * 获取JDBC URL
     */
    public static String getJdbcUrl(){
        return PropsUtil.getString(CONFIG_PROPS, ConfigConstant.JDBC_URL);
    }

    /**
     * 获取JDBC用户名
     */
    public static String getJdbcUsername(){
        return PropsUtil.getString(CONFIG_PROPS, ConfigConstant.JDBC_USERNAME);
    }

    /**
     * 获取JDBC密码
     */
    public static String getJdbcPassword(){
        return PropsUtil.getString(CONFIG_PROPS, ConfigConstant.JDBC_PASSWORD);
    }

    /**
     * 获取应用的JSP路径
     */
    public static String getAppJspPath(){
        return PropsUtil.getString(CONFIG_PROPS,ConfigConstant.APP_JSP_PATH, "/WEB-INF/view/");
    }

    /**
     * 获取应用的静态资源路径
     */
    public static String getAppAssetPath(){
        return PropsUtil.getString(CONFIG_PROPS, ConfigConstant.APP_ASSET_PATH, "/asset/");
    }

}

可以看到 ConfigHelper的最后两个方法设置了它们的默认值,也就是说,如果在配置文件中没有特别指明该配置项的值,那么就会用到它们的默认值。至此,配置方面先讲到这里,毕竟这章已经写得很长了...哈哈,最后附上完成这章内容后的框架项目(图一)和实例项目demo1(图二)的完整目录图,这样就会比较清晰了:

图一:    图二:


总结:

这一章写了4个常用工具类,1个维护常量的类,并且通过依赖它们用ConfigHelper实现了配置文件的读取,下一篇将会写一个类加载器,用来加载基础包名下的所有类(类似于Spring的扫包功能,如扫一个包下含有某个注解的全部类)。

【从零写javaweb框架】(三)开发一个类加载器

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《架构探险 从零开始写JavaWeb框架》这本书是一本关于如何从零开始构建JavaWeb框架的实践指南。这本书详细介绍了构建JavaWeb框架的基本原理、核心功能以及框架设计的各个方面。下面我将简要回答这个问题。 在这本书,作者首先介绍了JavaWeb框架的基本概念和开发背景,以及为什么需要自己去构建一个JavaWeb框架。接着,作者分析了现有的开源JavaWeb框架的优缺点,并提出了自己的设计思路。 在框架的设计方面,作者使用了简单、灵活、易扩展的原则。他详细解释了框架的各个组件的功能和交互方式,比如控制器、模型、视图和数据层等。除此之外,作者还介绍了如何实现框架的依赖注入和AOP等功能,以及如何处理请求和响应等核心功能。 在框架的实现过程,作者采用了优秀的开源框架作为基础,例如使用Servlet作为底层容器,使用Freemarker作为模板引擎,使用MySQL作为数据等。通过实际的代码示例和详细的解释,读者可以更好地理解每个组件的功能和实现方式。 总的来说,《架构探险 从零开始写JavaWeb框架》这本书通过将复杂的JavaWeb框架的设计和实现分解成简单的组件和步骤,帮助读者理解并掌握JavaWeb框架的构建过程。通过学习这本书,读者可以了解到一个完整的JavaWeb框架所需的各个组件和功能,并能够根据自己的需求进行定制和扩展。无论是对于初学者还是有一定经验的开发人员而言,这本书都是一本难得的实践指南。 ### 回答2: 《架构探险:从零开始写JavaWeb框架》是一本非常实用的书籍,主要介绍了如何从零开始开发一个完整的JavaWeb框架。这本书的作者对于JavaWeb开发有着丰富的经验,通过本书的学习,读者可以掌握开发框架所需的各种核心知识和技术。 在书,作者首先介绍了JavaWeb框架的概念和作用,以及为什么要从零开始开发一个框架。接着,作者详细讲解了框架的基本原则和设计思路,包括MVC模式、依赖注入、AOP等核心概念和技术。作者通过清晰的代码示例和实际案例,展示了如何使用这些技术来搭建一个可靠、高效的框架。 随后,作者开始逐步实现一个简单的JavaWeb框架。他从处理HTTP请求开始,依次实现了路由解析、参数绑定、控制器调用、视图渲染等功能。在实现的过程,作者注重详细讲解每个步骤的实现原理和技术细节,读者可以通过跟随书的示例代码进行实践和理解。 除了核心功能的实现,作者还介绍了一些框架的扩展功能,如连接池、事务管理、日志记录等。这些扩展功能可以使框架更加完善和灵活,提供更好的开发体验和性能优化。 总而言之,此书通过一个完整的JavaWeb框架实例,全面而系统地介绍了框架的设计与实现。读者通过学习本书,不仅可以掌握JavaWeb开发的核心知识和技术,还可以提升自己的架构设计能力和编码水平。无论是初学者还是有一定经验的开发者,都能从受益匪浅。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值