在启动时使用属性来确定要运行的代码段

时间:2016-09-09 12:31:19

标签: java design-patterns

在配置文件中设置了调试级别。我们在将它存储在类的变量中时获取该值,并从那里使用该值。在服务器启动期间,它会大约达到500-4000次,具体取决于环境。

是否有一个常见的工作或设计模式允许我们在开始时获取该值,然后根据其值运行代码库?最终目标是在if语句启动期间不必从其他类查询该参数400-4000次,以决定是否应该根据所使用的调试级别记录语句。

谢谢!

2 个答案:

答案 0 :(得分:0)

我称之为“ The Glob Pattern ”。我和企业级应用程序的主要应用程序架构师(超过10000个源文件)有类似的麻烦。

解决方法非常简单。我有这样的属性文件。

PHP7

这样的课程:

################################################
########## APPLICATION SETTINGS ################
################################################
appname                 = ${ecommfy.appname}
rootpath                = ${project.tomcat.directory}/webapps/${ecommfy.appname}
host                    = ${ecommfy.host}
appath                  = ${ecommfy.appath}

isSTAGING               = ${ecommfy.staging}
dbname                  = ${ecommfy.database.name}
dburl                   = ${ecommfy.database.url}
dbuser                  = ${ecommfy.database.username}
dbpass                  = ${ecommfy.database.password}
dbdriver                = ${ecommfy.database.driver}
adminSupportLanguage    = ${ecommfy.adminSupportLanguage}

Glob背后的想法是它在获取变量时读取属性文件。此属性文件只读一次,然后您可以使用public class Glob { protected final static Log logger = LogFactory.getLog(Glob.class); /* * ==================================================== * GLOB VARIABLES * ==================================================== */ private static boolean notLoadedYet = true; private static final String sep = java.io.File.separator; private static String fname = null; /* * ==================================================== * STATIC VARIABLES * ==================================================== */ private static String rootpath = ""; private static String host = ""; private static String contenthost = ""; private static String serverprefix = ""; private static String appname = ""; private static String appath = ""; private static String dburl = ""; private static String dbuser = ""; private static String dbpass = ""; private static String dbdriver = ""; private static String dataSourceLive = ""; private static String dataSouceStaging = ""; private static String defualtLanguageForAdmin = "en"; /* * ====================================================== * GLOB UTILITY MEHTODS * ====================================================== */ private static void checkLoadedYet() { if (notLoadedYet) { notLoadedYet = loadFromFile(); } } private static boolean loadFromFile() { InputStream fstream = null; try { Method method = null; method = Thread.class.getMethod("getContextClassLoader", new Class[]{}); ClassLoader classLoader = (ClassLoader) method.invoke(Thread.currentThread(), new Object[]{}); fstream = classLoader.getResourceAsStream("eCommFy.properties"); if (fstream != null) fname = "eCommFy.properties"; Properties properties = new Properties(); properties.load(fstream); readApplicationProperties(properties); fstream.close(); } catch (Exception ex) { logger.error("EC203: Error opening eCommFy.properties!", ex); } return false; } private static void readApplicationProperties(Properties props) { logger.info("Start Reading Application Proeprties..."); // Business Action logger.info("Done reading application properties..."); } } 做出影响流的决策。目前,我们根据应用程序是在分段还是生产环境中运行来做出巨大决策。

我们完全基于Glob并使用Spring来管理构建。 Maven符号是Maven属性,在应用程序编译时会被替换。

glob中的getter方法如下所示:

${ecommfy.appname}

答案 1 :(得分:0)

我不确定该问题的完整程度,但我认为它归结为与此类似的东西。

我们有一个具有各种日志严重性级别的系统:INFO,WARNING,ERROR

详细的层次结构:

  • INFO:INFO,ERROR
  • DEBUG:INFO,WARNING,ERROR

要解决这个问题(以它最基本的形式),我们可以为严重性定义一个接口:

public interface SeverityLoggingStrategy {
    public void log(String msg);
}

记录器:

public class Logger {
    private SeverityLoggingStrategy infoSeverity;
    private SeverityLoggingStrategy warningSeverity;
    private SeverityLoggingStrategy errorSeverity;

    public Logger(SeverityLoggingStrategy infoSeverity, SeverityLoggingStrategy warningSeverity, SeverityLoggingStrategy errorSeverity)         { 
        //... 
    }

    public void info(String msg) {
        this.infoSeverity.log(msg);
    }
    public void warn(String msg) {
        this.warningSeverity.log(msg);
    }
    public void error(String msg) {
       this.errorSeverity.log(msg);
    }
}

然后我们需要至少2个具体的严重性日志记录策略:

NonLoggingSeverityLoggingStrategy
LoggingSeverityLoggingStrategy

最后一个LoggerFactory可以根据详细级别将SeverityLoggingStrategy汇集到Logger

public class LoggerFactory {
    public forVerbosity(LogVerbosity verbosity) {
        if (verbosity == LogVerbosity.INFO) {
            return new Logger(
                new LoggingSeverityLoggingStrategy(),
                new NonLoggingSeverityLoggingStrategy(),
                new LoggingSeverityLoggingStrategy()
            );
        }

        //...
    }
}

系统启动时,您可以配置要使用的记录器的正确实例:

Logger logger = new LoggerFactory().forVerbosity(LogVerbosity.valueOf(config.logVerbosity()));

然后,客户端将使用各种日志严重性级别调用记录器,并且记录器将根据配置的详细程度使用适当的日志记录策略。

logger.warn('some warning'); //delegates to NonLoggingSeverityLoggingStrategy in INFO verbosity mode

显然你可能需要比这更多的灵活性,但是使用相同的方法,同时为更多的扩展点投入一些接口,你应该很高兴。