Utilizzando GroovyShell come “espressione valutatore / motore” (o: come riutilizzare GroovyShell)

StackOverflow https://stackoverflow.com/questions/5323114

  •  24-10-2019
  •  | 
  •  

Domanda

sto usando GroovyShell come "espressione valutatore / motore" dentro il mio programma. Esso accetta due ingressi: (a) uno o più script init (b) script definito dall'utente. Entrambi sono poi concatenati in fase di esecuzione come grossa fetta dello script (testo) e dei mangimi alla shell.

String initScripts = getFromDB()
String userScript = getFromUser()

def shell = new GroovyShell()
output = shell.evaluate(initScripts + userScript)

Il codice sopra verrà eseguito in un ciclo, dove il contenuto di userScript varieranno.

Finora, initScripts contiene solo definizioni di variabili (ad esempio def $yyyy = new Date().format('yyyy')) che potrebbero fare riferimento in userScript (ad esempio print "$yyyy 001").

C'è un approccio più efficiente per questo? (Ad esempio riutilizzando il guscio, come?) Perché in questo momento è di molto lenta.

Modifica Groovy è un must. Si prega di non raccomandare altro motore di scripting.

Modifica che sto pensando se GroovyShell può fare questo (pseudo-codice):

def shell = new GroovyShell()
shell.evaluate(initScripts)

for each userScript in DB {
    shell.put(userScript )
    def result = shell.evaluateThat()
    println "Result is $result"
}

È possibile? (L'ultima volta che ho cercato con Google non è possibile, ma spero che mi sbaglio)

È stato utile?

Soluzione

È possibile memorizzare nella cache il GroovyShell, non è necessario per creare uno nuovo sempre:

final static GroovyShell shell = new GroovyShell()

Anche se si esegue uno script molte volte si può memorizzare nella cache anche loro. È possibile creare un Script con GroovyShell.parse (String scriptText) , uso Script.run () per eseguire lo script.

Questa sezione della documentazione potrebbe aiutare troppo, invece di script è anche possibile creare oggetti groove dinamicamente.

Altri suggerimenti

Credo che si potrebbe evitare il peso di costruzione di un ambiente pieno Groovy ogni volta.

Dato che Java 6, v'è un supporto per lo scripting API in Java, che permette di utilizzare motori di script leggeri.

Per fare un esempio, vedere questa pagina nel sito web Groovy che spiega come per avviare uno script Groovy in un'applicazione Java utilizzando GroovyScriptEngineImpl .

avviso si può perdere alcune goodnesses groove, come forse uva Groovy, ma sarete in grado di

  • riutilizzare il motore di script
  • garantire i vostri evals di script in contesto di applicazione (eventualmente beneficiando di oggetti Java utilizzo)

Modifica una cosa importante da notare è che né GroovyScriptEngineImplGroovyShell può garantire alcun tipo di sicurezza dei thread, come qualsiasi script Groovy è libero di deporre le uova qualsiasi numero di thread. In realtà, l'unico modo per guarantte sicurezza dei thread sarebbe da installazione che vietano le operazioni di filettatura SecurityManager . Infatti, anche che non avrebbe la sicurezza dei thread garanzia (se questo filo di sicurezza potrebbe essere raggiunto solo garantendo tutta la vostra base di codice Java è thread-safe).

I finisce per fare questo:

def shell = new GroovyShell()
shell.evaluate(initScripts)

for( i in 1..count )
{
    output = shell.evaluate(userScripts);
}

E giusto per essere sicuri, si può mettere in shell ThreadLocal o in piscina.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top