Кодирование JavaScript на JVM
Что такое Нашорн?
Nashorn - это движок JavaScript для JVM, выпущенный вместе с Java 8. Nashorn состоит из встроенного интерпретатора JavaScript и инструмента командной строки. Задача Nashorn - реализовать высокопроизводительную среду выполнения JavaScript на Java с собственной JVM. Используя Nashorn, разработчик может встраивать JavaScript в приложение Java, а также вызывать методы и классы Java из кода JavaScript, обеспечивая бесшовную интеграцию между двумя языками.
Роль Нэшорна в сценариях на стороне сервера
написание серверного JS в настоящее время является обычным требованием. Поскольку JavaScript становится популярным в серверном программировании - например, Node.js, Nashorn обеспечивает интеграцию приложений JavaScript и Java путем доступа к функциям JavaScript в Java и наоборот. Он напрямую компилирует код JavaScript в памяти и передает байт-код Java в JVM. Добавляя поддержку серверных сценариев к вашим продуктам с помощью Nashorn, мы можем легко настроить продукт в соответствии с различными требованиями без необходимости каждый раз перекомпилировать.
Теперь давайте посмотрим на некоторые функции Nashorn.
Вызов функций JavaScript из Java
Простой пример hello world.
ScriptEngine nashorn = new ScriptEngineManager().getEngineByName ("nashorn"); nashorn.eval("print('Hello, world')");
Мы можем передать весь файл .js в метод .eval () для более серьезных случаев использования следующим образом.
ScriptEngine engine = new ScriptEngineManager().getEngineByName ("nashorn"); engine.eval(new FileReader("script.js"));
Передача объектов Java в качестве аргументов функции и возвращаемых значений из функции JS в вызывающий метод Java
- приведите механизм сценария к Invocable, чтобы иметь возможность вызывать функцию.
- NashornScriptEngine определяет метод invokeFunction для вызова функции JavaScript для заданного имени.
String script = "function var printHello = function(name) { print('Hello, ' + name); return 'hello from Javascript'; };";
ScriptEngine engine = new ScriptEngineManager().getEngineByName ("nashorn"); Invocable invocable = (Invocable) engine; Object result = invocable.invokeFunction("printHello
", "Sathya");
Вызов методов Java из JavaScript
Мы можем ссылаться на классы Java из JavaScript, используя расширение API Java.type. Это похоже на импорт классов в коде Java.
var MyJavaClass = Java.type (‘com.test.JavaScriptTest’); var result = MyJavaClass.func1 (‘Sathya’); //call a function named 'func1' print (result);
Вызов API Java из JavaScript
Вариант 1 - укажите полное имя, то есть имя пакета
var joinString=Java.type (“java.lang.String”) joinString.join (“ “, “Hello”, “World”)
Вариант 2. Доступ к глобальным объектам, определенным для API Java, по имени пакета.
java.lang.String.join (“ “,”Hello”,”World”)
ScriptObjectMirror
ScriptObjectMirror
является частью jdk.nashorn.api
и предназначен для использования в клиентском коде вместо внутренних классов.
Этот зеркальный объект является представлением базового объекта JavaScript и обеспечивает доступ к нему, его методам и свойствам.
ScriptObjectMirror
реализует интерфейс Map
.
Облегчает вызов функций-членов для объектов JavaScript из Java. Пример будет следующим.
/*Person
is a JavaScript type with some properties and a function.*/ function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; this.getFullName = function() { return this.firstName + ' ' + this.lastName; } }
Функцию getFullName()
можно вызвать на ScriptObjectMirror
через callMember()
public static void getFullName(ScriptObjectMirror person) {
System.out.println("Full name is: " + person.callMember("getFullName"));
}
Привязки / Контекст
ScriptContext
содержит одну или несколько привязок, каждая из которых связана с областью. По умолчанию есть две области: ENGINE_SCOPE
GLOBAL_SCOPE
Когда создается движок Nashorn, он создает контекст по умолчанию: ScriptContext defaultContext = engine.getContext();
ENGINE_SCOPE
контекста по умолчанию - это область, в которой хранятся «глобальные» объекты и функции (Object
, Function
, Math
, RegExp
, parseInt
и т. Д.).
GLOBAL_SCOPE
используется всеми движками, созданными одним и тем же ScriptEngineManager
.
Вы можете хранить переменные в контексте (использование области необязательно, по умолчанию ENGINE_SCOPE
):
ScriptContext context = engine.getContext(); // stores an object under the key `myKey` in the (engine scoped) context context.setAttribute("myKey", object, ScriptContext.ENGINE_SCOPE); // retrieves the object with key `myKey` from (engine scoped) context context.getAttribute("myKey", ScriptContext.ENGINE_SCOPE);
Bindings b = context.getBindings(ScriptContext.ENGINE_SCOPE); b.get("Object"); // gets ECMAScript "Object" constructor b.get("undefined"); // ECMAScript 'undefined' value
Если переменная не найдена в ENGINE_SCOPE
, выполняется поиск GLOBAL_SCOPE
привязок.
Java Beans
С Nashorn вы получаете прямой доступ к свойствам Java-бина, больше не нужно использовать геттеры и сеттеры:
var Date = Java.type('java.util.Date');
var date = new Date();
date.year += 1900; // -> no setter!
print(date.year); /
Свойства привязки
Вы можете привязать свойства одного объекта к другому:
var o1 = {}; var o2 = { foo: 'bar' };
Object.bindProperties(o1, o2);
print(o1.foo); o1.foo = 'John'; print(o2.foo);
Чтобы получить полный список возможностей Nashorn, вы можете обратиться к [1].
Пример использования Nashorn
Предположим, у нас есть IAM-решение, обеспечивающее адаптивную схему аутентификации, написанную исключительно на Java.
В адаптивной схеме аутентификации мы привязываем процесс аутентификации к внешним параметрам. Например, контекстуальные факты - сколько раз пользователь пытался войти в систему, специфические атрибуты пользователя - IP-адрес пользователя, местоположение, устройство, набор привилегий и т. Д. В этой схеме администраторы должны иметь возможность изменять потоки входа и аутентификации на основе это динамические данные.
Теперь предположим, что вы хотите продать это программное обеспечение нескольким клиентам. У каждого клиента могут быть разные требования, и может потребоваться настройка вашего решения. Если все решение реализовано на Java, нам может быть сложно изменить бизнес-логику в соответствии с требованиями каждого клиента, и это потребует серьезных изменений уровня кода и перекомпиляции. Наряду с этим идут обширные циклы тестирования изменений на уровне кода. Это может стать обузой для разработчика программного обеспечения и, несомненно, потребует большей части его ресурсов - времени, усилий, оборудования и т. Д.
В качестве решения вместо написания программного обеспечения исключительно на Java мы можем добавить в продукт поддержку сценариев с использованием Nashorn. С помощью сценариев Nashorn мы предоставляем клиентам, для которых мы пишем это программное обеспечение, возможность настраивать бизнес-логику под требования каждого клиента без перекомпиляции кода.
Теперь мы можем легко продавать программное обеспечение нескольким клиентам и подробно рассказывать о его функциях. Клиенты могут реализовать свою собственную логику с привлечением пользовательских сценариев, написав небольшой фрагмент кода JavaScript с бизнес-правилами, зависящими от клиента, и их требования будут удовлетворены за счет минимального участия разработчика решения. Во время выполнения Nashorn будет выполнять эти сценарии, включая динамические параметры.
Плюсы
- Добавьте в свои продукты поддержку сценариев, которые позволят вам или вашим пользователям быстро разрабатывать и изменять продукт в соответствии с различными потребностями без необходимости перекомпилировать или изучать внутреннюю работу продукта.
- Предоставляет возможность изменять бизнес-логику вашего программного обеспечения на лету без изменения кода Java и перекомпиляции кода в соответствии с требованиями каждого клиента.
- Повышение настраиваемости приложений. возможность реализации основных частей бизнес-логики и точек расширения, поскольку JavaScript упрощает изменение во время выполнения.
- Такое разделение частей приложения может позволить гораздо быстрее исправить ошибки и добавить дополнительные функции.
- Сокращает общий цикл DTAP программного обеспечения
- Обеспечивает гораздо более быстрое выполнение и многопоточность JavaScript при работе в Java JRE.
- Обеспечение доступа ко всем преимуществам Java - обширным библиотекам, оптимизации кода, обширным сетям поддержки и т. Д.
- Возможность использования гибкого языка с динамической типизацией, с которым уже знакомы многие программисты.
- Значительные улучшения производительности по сравнению с Mozilla's Rhino.
- Nashorn очень легко интегрируется и используется с JavaFX. Пользователи могут очень легко интерпретировать приложение-скрипт JavaFX с помощью Nashorn с помощью инструмента командной строки jjs.