Uso de GroovyShell como "Evaluador/motor de expresión" (o: Cómo reutilizar Groovyshell)

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

  •  24-10-2019
  •  | 
  •  

Pregunta

Estoy usando GroovyShell Como un "evaluador/motor de expresión" dentro de mi programa. Acepta dos entradas: (a) uno o más scripts de inicio (b) script definido por el usuario. Ambos se concatenan en tiempo de ejecución como una gran parte del script (texto) y se alimentan a la carcasa.

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

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

El código anterior se ejecutará en un bucle, donde el contenido de userScript variará.

Hasta aquí, initScripts Solo contienen definiciones variables (por ejemplo def $yyyy = new Date().format('yyyy')) que podría ser referenciado en userScript (p.ej print "$yyyy 001").

¿Hay algún enfoque más eficiente para esto? (Por ejemplo, reutilizando el caparazón, ¿cómo?) Porque ahora mismo es muy lento.

Editar: Groovy es imprescindible. No recomiende otro motor de secuencias de comandos.

Editar: Estoy pensando si Groovyshell puede hacer esto (pseudo-código):

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

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

es posible? (La última vez que busqué en Google no es posible, pero espero que me equivoque)

¿Fue útil?

Solución

Puede almacenar en caché el groovyshell, no necesita crear uno nuevo siempre:

final static GroovyShell shell = new GroovyShell()

Además, si ejecuta un script muchas veces, también puede almacenarlos en caché. Puedes crear un Script con Groovyshell.Parse (String scriptText), usar Script.run () para ejecutar el guión.

Esta sección De la documentación también podría ayudar, en lugar de scripts, también puede crear objetos maravillosos dinámicamente.

Otros consejos

Supongo que podría evitar el peso de construir un ambiente maravilloso completo cada vez.

Desde Java 6, hay un soporte de API de secuencias de comandos en Java, que le permite usar motores de secuencias de comandos livianos.

Como ejemplo, ver Esta página en el sitio web Groovy Explicando cómo iniciar un guión groovy en una aplicación Java usando GroovyScriptEngineImpl.

Observe que puede perder algunas bondades maravillosas, como tal vez Groovy Grape, pero podrá

  • Reutilice su motor de guión
  • Asegúrese de que su script evalte en el contexto de la aplicación (que eventualmente se beneficia del uso de objetos Java)

EDITAR Una cosa importante a notar es que ni GroovyScriptEngineImpl ni GroovyShell Puede garantizarle cualquier tipo de seguridad de hilo, ya que cualquier guión Groovy es libre de generar cualquier número de hilo. De hecho, la única forma en que podría garantizar la seguridad del hilo sería por Instalación de un SecurityManager Prohibir las operaciones de hilo. De hecho, incluso eso no garantizaría la seguridad del hilo (ya que la seguridad de este hilo solo podría lograrse asegurando que toda su base de código Java sea segura de los subprocesos).

Termino haciendo esto:

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

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

Y solo para estar a salvo, puedes poner shell en ThreadLocal o piscina.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top