Apache Velocity禁用模板&资源缓存

时间:2016-06-21 19:52:50

标签: java spring-mvc velocity

我有一个Spring Boot应用程序,它公开了一个用于呈现相对简单的速度模板的API。模板使用#parse来包含其他几个模板,否则会写出从Java层传递给它的一些基本变量。模板位于JAR文件中,因此它们是从类路径加载的。我使用以下速度引擎设置,即每次请求即时创建:

    VelocityEngine ve = new VelocityEngine();
    ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
    ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
    ve.setProperty("classpath.resource.loader.cache", "false");
    ve.setProperty("velocity.engine.resource.manager.cache.enabled", "false");
    ve.setProperty("resource.manager.cache.enabled", "false");
    ve.init();

模板的多个部分意味着每个请求是唯一的(资源用作对简单的Spring MVC控制器的响应),因此我需要禁用模板资源的缓存。我已按原样尝试了上述配置,并在velocity.properties中的src/main/resources文件中定义了该配置,但在重新启动应用程序之前,更改模板或文件并未“生效”。

执行this documentation页面所说的内容似乎没有帮助(事实上,您可以看到它在上面做了什么)。

上面的引擎代码位于Spring Component类中,甚至在将VelocityEngine内容移动到静态最终字段时,每次初始化速度上下文都没有帮助。

如何强制Spring / Velocity加载模板&每次都包括资源?

2 个答案:

答案 0 :(得分:1)

您只需要classpath.resource.loader.cache配置密钥。由于Velocity中的所有缓存都默认为false,因此您甚至不需要它。

此外,无需在每次请求时重新初始化VelocityEngine。

我使用以下小测试程序检查了修改后正确重新加载的资源:

import java.io.PrintWriter;
import java.io.Writer;
import java.util.Scanner;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.runtime.RuntimeConstants;
import org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader;    

public class Test
{
    public static void main(String args[])
    {
        try
        {
            VelocityEngine ve = new VelocityEngine();
            ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
            ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
            // next line not needed since 'false' is the default
            // ve.setProperty("classpath.resource.loader.cache", "false");
            ve.init();

            VelocityContext context = new VelocityContext();
            Writer writer = new PrintWriter(System.out);
            Scanner scan = new Scanner(System.in);
            while (true)
            {
                System.out.print("> ");
                String str = scan.next();
                context.put("foo", str);
                ve.mergeTemplate("test.vm", "UTF-8", context, writer);
                writer.flush();
            }
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

如果它在你的情况下不起作用,并且特别是如果你在每次请求时重新初始化Velocity,那么它肯定是Spring本身的ClassLoader缓存问题。

因此,您应该检查Spring Hot Swapping guide以了解如何禁用缓存。我想对Spring有更好了解的人可以给你一个关于如何在这种特殊情况下继续进行的提示。

答案 1 :(得分:0)

令人尴尬的是,这是因为我需要在更改模板或资源后通过IntelliJ进行编译,例如使用Ctrl + F9。感谢@Claude Brisson的帮助。