Использование Groovyshell в качестве «оценки экспрессии/двигателя» (или: как повторно использовать Groovyshell)

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

  •  24-10-2019
  •  | 
  •  

Вопрос

я использую GroovyShell как «оценщик выражения/двигатель» внутри моей программы. Он принимает два входа: (а) один или несколько сценариев инициации (б), определяемый пользователем сценарий. Оба затем объединяются во время выполнения как большой кусок сценария (текст) и подают в оболочку.

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

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

Приведенный выше код будет работать в цикле, где содержимое userScript будет варьироваться.

Уже, initScripts только содержат определения переменных (например, def $yyyy = new Date().format('yyyy')), на что можно ссылаться в userScript (например print "$yyyy 001").

Есть ли более эффективный подход для этого? (Например, повторно используя оболочку, как?) Потому что сейчас это очень медленный.

Редактировать: Groovy является обязательным. Пожалуйста, не рекомендуйте другой двигатель сценариев.

Редактировать: Я думаю, может ли Groovyshell это сделать (псевдокод):

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

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

Это возможно? (В прошлый раз, когда я гуглил, это невозможно, но я надеюсь, что я ошибаюсь)

Это было полезно?

Решение

Вы можете кэшировать Groovyshell, вам не нужно всегда создавать новый:

final static GroovyShell shell = new GroovyShell()

Также, если вы запускаете один сценарий много раз, вы тоже можете их кэшировать. Вы можете создать Script с Groovyshell.parse (String scripttext), использовать Script.run () запустить сценарий.

Эта секция Документации также может помочь, вместо сценариев вы также можете динамически создавать Groovy объекты.

Другие советы

Я полагаю, вы могли бы избежать веса построения полной громкой среды каждый раз.

Со времен Java 6 в Java есть поддержка API сценариев, которая позволяет использовать легкие сценаристы.

В качестве примера см. Эта страница на Groovy Sames Объясняя, как запустить отличный сценарий в приложении Java с помощью GroovyScriptEngineImpl.

Обратите внимание, что вы можете потерять несколько хороших достоин

  • Повторно используйте свой сценарий
  • Убедитесь, что ваш скрипт Evals в контексте приложения (в конечном итоге пользуется использованием объектов Java)

РЕДАКТИРОВАТЬ Одна важная вещь, которую нужно заметить, это то, что ни один GroovyScriptEngineImpl ни GroovyShell Можно гарантировать вам любую безопасность потока, так как любой отличный сценарий может порождать любое количество потоков. На самом деле, единственный способ гарантировать безопасность потока, - это было бы Установка SecurityManager Запрещение операций потока. На самом деле, даже это не гарантирует безопасность потока (так как безопасность этой потока может быть достигнута только путем обеспечения всей вашей базы кода Java безопасным потоком).

Я в конечном итоге делаю это:

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

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

И просто чтобы быть в безопасности, вы можете положить shell в ThreadLocal или бассейн.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top