2016-06-21 13 views
0

Ich habe eine Spring-Boot-Anwendung, die eine API zum Rendern einer relativ einfachen Geschwindigkeitsvorlage zur Verfügung stellt. Die Vorlage verwendet #parse, um einige andere Vorlagen einzuschließen, und schreibt ansonsten einige Basisvariablen aus der Java-Ebene aus. Die Vorlagen befinden sich in der JAR-Datei und werden daher aus dem Klassenpfad geladen. Ich verwende die folgende Geschwindigkeit Motor-Setup, das on-the-fly-per-Anfrage erstellt wird:Apache Velocity deaktivieren Vorlage & Ressourcen-Caching

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(); 

Mehrere Teile der Vorlage sollen pro Anforderung eindeutig sein (die Ressource als Antwort auf eine einfache Feder verwendet wird MVC-Controller), daher muss ich das Zwischenspeichern der Vorlagenressourcen deaktivieren. Ich habe die obige Konfiguration ausprobiert, wie es ist, und es in einer velocity.properties Datei definieren, die in src/main/resources ist, aber das Ändern der Vorlage oder der Dateien wird nicht wirksam, bis ich die Anwendung neu starte.

Doing was this documentation Seite sagt, scheint nicht zu helfen (in der Tat können Sie sehen, was es oben tut).

Der Motorcode oben ist in einer Spring Component Klasse und selbst wenn die VelocityEngine Sachen zu einem statischen Endfeld bewegen und nur die Geschwindigkeit Kontext jedes Mal zu initialisieren hat nicht geholfen.

Wie kann Spring/Velocity zum Laden von Vorlagen & enthaltene Ressourcen jedes Mal erzwingen?

Antwort

0

Embarasingly war, weil ich kompilieren durch IntelliJ einmal Vorlagen oder Ressourcen, z. mit Strg + F9. Danke an @Claude Brisson für die Hilfe.

1

Sie benötigen nur den Konfigurationsschlüssel classpath.resource.loader.cache. Und da das gesamte Caching in Velocity standardmäßig auf "false" eingestellt ist, brauchen Sie es nicht einmal.

Außerdem muss die VelocityEngine nicht bei jeder Anforderung neu initialisiert werden.

checkte ich mit dem folgende kleinen Testprogramm, das Ressource, wo richtig, wenn geändert reloaded:

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(); 
     } 
    } 
} 

Wenn es nicht in Ihrem Fall nicht funktioniert, und besonders, wenn Sie bei jeder Anfrage Geschwindigkeit neu initialisieren , dann ist es sicher ein ClassLoader-Caching-Problem in Spring selbst.

Sie sollten also Spring Hot Swapping guide überprüfen, um zu sehen, wie Sie das Caching deaktivieren. Ich nehme an, jemand mit einer besseren Kenntnis von Spring kann Ihnen einen Hinweis geben, wie Sie in diesem speziellen Fall vorgehen sollten.

+0

Sind die VelocityEngine-Instanzen threadsafe? Würde eine statische Referenz funktionieren? –

+0

Ja, Velocity ist Thread-sicher. Aber im Gegensatz zu meinem kleinen Beispiel oben ist der VelocityContext nicht und muss wieder instanziiert werden. –

+0

Ja, ich halte jetzt einen 'statischen finalen' Verweis auf die 'VelocityEngine' -Instanz und erzeuge den 'VelocityContext' in der Methode, die die Vorlagen zusammenführt. Wird in Kürze testen und akzeptieren. Vielen Dank! –

Verwandte Themen