En utilisant GroovyShell comme « évaluateur d'expression / moteur » (ou: Comment réutiliser GroovyShell)

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

  •  24-10-2019
  •  | 
  •  

Question

J'utilise GroovyShell comme un « évaluateur d'expression / moteur » à l'intérieur de mon programme. Il accepte deux entrées: (a) un ou plusieurs scripts d'initialisation (b) script défini par l'utilisateur. Les deux sont ensuite concaténés lors de l'exécution en tant que gros morceau de l'écriture (texte) et l'alimentation à la coquille.

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

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

Le code ci-dessus se déroulera en boucle, où le contenu de userScript peuvent varier.

Jusqu'à présent, initScripts ne contiennent que des définitions variables (par exemple def $yyyy = new Date().format('yyyy')) qui pourraient être référencés dans userScript (par exemple print "$yyyy 001").

Y at-il approche plus efficace pour cela? (La coquille réutilisant Par ex, comment?) Parce qu'en ce moment il de très lent.

Modifier Groovy est un must. S'il vous plaît ne recommande pas autre moteur de script.

Modifier Je pense que GroovyShell peut le faire (pseudo-code):

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

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

Est-ce possible? (La dernière fois que je googlé ce n'est pas possible, mais j'espère que je me trompe)

Était-ce utile?

La solution

Vous pouvez mettre en cache la GroovyShell, vous n'avez pas besoin de créer un nouveau toujours:

final static GroovyShell shell = new GroovyShell()

Aussi, si vous exécutez un script plusieurs fois, vous pouvez les mettre en cache aussi. Vous pouvez créer un Script avec GroovyShell.parse (String scriptText) , l'utilisation Script.run () pour exécuter le script.

Cette section de la documentation peut aider aussi, au lieu de scripts, vous pouvez également créer des objets groovy dynamiquement.

Autres conseils

Je suppose que vous pourriez éviter le poids de la construction d'un environnement groovy complet à chaque fois.

Depuis Java 6, il y a un support API de scripts en Java, ce qui vous permet d'utiliser les moteurs de script légers.

À titre d'exemple, voir cette page sur le site groovy expliquant comment pour lancer un script groovy dans une application Java en utilisant GroovyScriptEngineImpl .

avis vous pouvez perdre quelques bontés groovy, comme peut-être raisin Groovy, mais vous serez en mesure de

  • réutiliser votre moteur de script
  • vous assurer que vos evals de script dans le contexte de l'application (éventuellement bénéficier de Java utilisation des objets)

EDIT Une chose importante à noter est que ni GroovyScriptEngineImpl ni GroovyShell peut vous garantir tout type de fil de sécurité, comme tout script groovy est libre de reproduire un certain nombre de fil. En fait, la seule façon que vous pouvez guarantte la sécurité des threads serait par l'installation d'une des opérations de fil de securityManager interdisant. En fait, même ce ne garantirait pas la sécurité des threads (comme ce fil de sécurité ne pouvait être atteint en sorte que tous votre base de code Java est thread-safe).

Je finis par faire ceci:

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

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

Et juste pour être sûr, vous pouvez mettre en shell ThreadLocal ou à la piscine.

scroll top