【问题标题】:How to reload properties file without rebooting Tomcat如何在不重新启动 Tomcat 的情况下重新加载属性文件
【发布时间】:2011-04-04 04:00:40
【问题描述】:

我使用方法从类路径加载一个属性文件:

    String cheminFichier = new StringBuilder(100).append(classeBP.getPackage().getName().replace(".", "/")).append(File.separator).append(
        REPERTOIRE_MAPPING).append(nomFichier).append(".properties").toString();
    InputStream isMapping = Thread.currentThread().getContextClassLoader().getResourceAsStream(cheminFichier.toString());
    if (isMapping == null)
    {
        throw new ServiceMappingException("Erreur lors du chargement du mapping du service. Le fichier "
            + cheminFichier + " n'existe pas.");
    }
    else
    {
        Properties mapping = new Properties();
        try
        {
            mapping.load(isMapping);
        }
        catch (IOException e)
        ...
    }

好的,它的工作。但是如果我在 Tomcat 运行时修改了属性文件的内容,更改将被忽略。 它不像类那样热重载。

我的上下文配置了reloadable="true" 选项,Thread.currentThread().getContextClassLoader() 返回的类加载器是 WEBAPP 类加载器(不是系统类加载器或其他)。

我读到可以使用 ServletContext.getResourceAsStream,但我无法访问 servlet 上下文。

这是 Tomcat 5.5。

有什么想法吗?如果没有,您是否有强制重新加载特定资源(我的属性文件)的解决方案?

谢谢!

【问题讨论】:

    标签: java tomcat classloader


    【解决方案1】:

    实际上,您的 web 应用程序确实可以在各个点访问 ServletContext。例如,您可以使用ServletRequest.getServletContext() 获取它,或者从通过ServletContextListener 回调获得的ServletContextEvent 获取。


    这有点离题,但你应该意识到这段代码:

    String cheminFichier = new StringBuilder(100).append(classeBP.getPackage().getName().replace(".", "/")).append(File.separator).append(
        REPERTOIRE_MAPPING).append(nomFichier).append(".properties").toString();
    

    可以/应该写成:

    String cheminFichier = classeBP.getPackage().getName().replace(".", "/")) +
        File.separator + REPERTOIRE_MAPPING + nomFichier + ".properties";
    

    在此处显式使用StringBuilder 并没有性能优势此处,因为Java 编译器会将串联编译为相同的代码。

    如果串联涉及循环,您只需要使用StringBuilder

    【讨论】:

    • 在离题主题中,你不应该用法语编码,但这是另一个争论。
    • @Colin - 我不会走那么远,但是用法语到英语词典来阅读 Java 有点尴尬。不过印尼语会很好:-)
    • 感谢您的回答。我会试试的。关于StringBuilder,我不同意你的观点(也许我错了......)。我用 100 个字符初始化 StringBuilder,所以当字符串增长时 Java 不会重新分配,不是吗?关于法语编码,我同意你的观点:)但我没有写规则..
    • @Abalataur - 关于 StringBuilder,这取决于您的估计大小与实际大小的接近程度。如果您的估计接近,那么您可能会赢一点。如果不是,你不会。特别是,如果它很大,那么您将损失很大。但无论哪种方式,这都是一种可能不值得的优化……除非分析另有说明。
    【解决方案2】:

    您可以使用支持automatic reloadingCommons Configuration 之类的东西。

    【讨论】:

      【解决方案3】:

      您仍然可以使用 Tomcat 管理器重新加载您的应用程序。

      【讨论】:

      • 是的,但这正是我想要避免的。我的应用程序需要大约 1 分钟才能启动,所以一旦我更改了属性文件,我就不会重新加载整个应用程序。
      猜你喜欢
      • 2017-09-09
      • 2012-01-28
      • 2015-05-09
      • 1970-01-01
      • 1970-01-01
      • 2012-05-13
      • 2014-03-11
      • 1970-01-01
      • 2015-11-02
      相关资源
      最近更新 更多