GroovyShellを「Expression Evaluator/Engine」として使用する(または:GroovyShellを再利用する方法)
-
24-10-2019 - |
質問
私は使用しています GroovyShell
私のプログラム内の「式評価者/エンジン」として。 (a)1つ以上のinitスクリプト(b)ユーザー定義のスクリプト:2つの入力を受け入れます。両方とも、実行時にスクリプトの大きな塊(テキスト)として連結され、シェルにフィードが付けられます。
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"
).
これにこれ以上の効率的なアプローチはありますか? (たとえば、シェルを再利用して、どうやって?) とても スロー。
編集: グルーヴィーは必須です。他のスクリプトエンジンをお勧めしないでください。
編集: 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()
また、1つのスクリプトを何度も実行すると、キャッシュすることもできます。 aを作成できます Script
と GroovyShell.Parse(StringScriptText), 、 使用する script.run() スクリプトを実行します。
このセクション ドキュメントの場合も役立つかもしれませんが、スクリプトの代わりに、Groovyオブジェクトを動的に作成することもできます。
他のヒント
毎回、完全なグルーヴィー環境を構築する重量を避けることができると思います。
Java 6以来、JavaにはScripting APIサポートがあり、軽量スクリプトエンジンを使用できます。
例として、参照してください このページは、Groovy Webサイトです Javaアプリケーションでグルーヴィーなスクリプトを開始する方法を説明する方法 GroovyScriptEngineImpl
.
たぶんグルーヴィーなブドウのように、あなたはいくつかのグルーヴィーな良さを失うかもしれませんが、あなたはできるでしょう
- スクリプトエンジンを再利用します
- スクリプトがアプリケーションのコンテキストで回避することを確認します(最終的にはJavaオブジェクトの使用の恩恵を受ける)
編集 注意すべき重要なことの1つは、どちらもそうではないということです GroovyScriptEngineImpl
または GroovyShell
あらゆる種類のスレッドの安全性を保証することができます。あらゆるグルーヴィーなスクリプトは、任意の数のスレッドを自由に生成できます。実際、スレッドの安全性を保証できる唯一の方法は、 セキュリティマネージャーのインストール スレッド操作を禁止します。実際、それでさえスレッドの安全性を保証するものではありません(このスレッドの安全性は、すべてのJavaコードベースがスレッド安全であることを保証することによってのみ達成できます)。
私はこれを行うことになります:
def shell = new GroovyShell()
shell.evaluate(initScripts)
for( i in 1..count )
{
output = shell.evaluate(userScripts);
}
そして、安全にするために、あなたは置くことができます shell
の ThreadLocal
またはプール。