Как запустить java программу с аргументами
В этом уроке мы будем обрабатывать аргументы командной строки на Java. Мы получим к ним доступ и прочитаем их, а также сопоставим аргументы с типами данных, чтобы изменить поток кода.
Вступление
Аргументы (параметры) командной строки-это строки текста, используемые для передачи дополнительной информации программе при запуске приложения через интерфейс командной строки (CLI) операционной системы.
В этом уроке мы будем обращаться к аргументам (параметрам), переданным в основной метод Java-приложения, и читать их. Мы также сопоставим их с различными типами данных, чтобы мы могли обрабатывать их и изменять поток кода на основе входных данных.
Доступ к Аргументам Командной Строки
Точкой входа для каждой программы Java является метод main() :
Аргументы, переданные программе при ее инициализации, хранятся в массиве args . Кроме того, Java также поддерживает vararg в этом месте:
Тем не менее, мы можем легко получить доступ к каждому аргументу, переданному в этот метод. Давайте начнем с того, что распечатаем их один за другим:
Затем мы скомпилируем этот файл .java :
После чего мы сможем запустить его:
Сопоставление аргументов с типами данных
Сами аргументы представляют собой массив строк. Так что на самом деле все, что мы передаем, – это Строка. Тем не менее, мы также можем конвертировать строки в различные типы данных:
Давайте сделаем это:
Теперь давайте снова скомпилируем код:
А затем давайте запустим его без каких-либо аргументов:
Git Essentials
Ознакомьтесь с этим практическим руководством по изучению Git, содержащим лучшие практики и принятые в отрасли стандарты. Прекратите гуглить команды Git и на самом деле изучите это!
Нас встречают с:
Если мы приведем аргументы:
Установка аргументов в IDE
Это предполагает, что вы запускаете код через командную строку, что не всегда так. Большинство людей используют IDE для работы над своими проектами, в которых вместо этого есть удобная кнопка “Запустить”.
К счастью, вы можете указать IDE передать эти аргументы в вызов run. Вот примеры того, как вы можете сделать это с помощью некоторых популярных идей:
Затмение
В разделе “Выполнить” -> “Конфигурации запуска” :
IntelliJ
В разделе “Выполнить” -> “Редактировать конфигурации” :
Вывод
В этой статье мы рассмотрели, как мы можем получить доступ к аргументам командной строки, передаваемым в приложение Java при его запуске.
Затем мы сопоставили переданные аргументы с различными типами данных и обработали их соответствующим образом. Имея это в виду, легко создавать простые инструменты CLI и изменять поток кода на основе переданных аргументов.
Сейчас уже никто не создает программы в консоли. Используя любимую IDE, разработчик чувствует себя неуютно за чужим компьютером, где её нет.
Решив разобраться в работе Ant и Maven, я поймал себя на том, что не смогу собрать приложение без них в консоли.
В данной статье я постарался уместить все этапы проектирования демонстрационного приложения, чтобы не искать справку по каждой команде на просторах Интернета.
От простого к .
Каждая программа обычно содержится в отдельном каталоге. Я придерживаюсь правила создавать в этом каталоге по крайней мере две папки: src и bin. В первой содержатся исходные коды, во второй — результат компиляции. В данных папках будет структура каталогов, зависящая от пакетов.
Один файл
Можно сделать и без лишних папок.
Берем сам файл HelloWorld.java.
Переходим в каталог, где лежит данный файл, и выполняем команды.
В данной папке появится файл HelloWorld.class. Значит программа скомпилирована. Чтобы запустить
Отделяем бинарные файлы от исходников
Теперь сделаем тоже самое, но с каталогами. Создадим каталог HelloWorld и в нем две папки src и bin.
Компилируем
Здесь мы указали, что бинарные файлы будут сохраняться в отдельную папку bin и не путаться с исходниками.
Используем пакеты
А то, вдруг, программа перестанет быть просто HelloWorld-ом. Пакетам лучше давать понятное и уникальное имя. Это позволит добавить данную программу в другой проект без конфликта имен. Прочитав некоторые статьи, можно подумать, что для имени пакета обязательно нужен домен. Это не так. Домены — это удобный способ добиться уникальности. Если своего домена нет, воспользуйтесь аккаунтом на сайте (например, ru.habrahabr.mylogin). Он будет уникальным. Учтите, что имена пакетов должны быть в нижнем регистре. И избегайте использования спецсимволов. Проблемы возникают из-за разных платформ и файловых систем.
Поместим наш класс в пакет с именем com.qwertovsky.helloworld. Для этого добавим в начало файла строчку
В каталоге src создадим дополнительные каталоги, чтобы путь к файлу выглядел так: src/com/qwertovsky/helloworld/HelloWorld.java.
Компилируем
В каталоге bin автоматически создастся структура каталогов как и в src.
Если в программе несколько файлов
HelloWorld.java
Adder.java
Ошибка возникла из-за того, что для компиляции нужны файлы с исходными кодами классов, которые используются (класс Calculator). Надо указать компилятору каталог с файлами с помощью ключа -sourcepath.
Компилируем
Если удивляет результат
Есть возможность запустить отладчик. Для этого существует jdb.
Сначала компилируем с ключом -g, чтобы у отладчика была информация.
Отладчик запускает свой внутренний терминал для ввода команд. Справку по последним можно вывести с помощью команды help.
Указываем точку прерывания на 9 строке в классе Calculator
Запускаем на выполнение.
Чтобы соориентироваться можно вывести кусок исходного кода, где в данный момент находится курссор.
Узнаем, что из себя представляет переменная а.
Выполним код в текущей строке и увидим, что sum стала равняться 2.
Поднимемся из класса Adder в вызвавший его класс Calculator.
Удаляем точку прерывания
Можно избежать захода в методы, используя команду next.
Проверяем значение выражения и завершаем выполнение.
Хорошо бы протестировать
Запускаем. В качестве разделителя нескольких путей в classpath в Windows используется ';', в Linux — ':'. В консоли Cygwin не работают оба разделителя. Возможно, должен работать ';', но он воспринимается как разделитель команд.
Создадим библиотеку
Класс Calculator оказался полезным и может быть использован во многих проектах. Перенесем всё, что касается класса Calculator в отдельный проект.
Измените также назавания пакетов в исходных текстах. В HelloWorld.java нужно будет добавить строку
Делаем архив jar
С помощью ключа -C мы запустили программу в каталоге bin.
Надо узнать, что у библиотеки внутри
Можно распаковать архив zip-распаковщиком и посмотреть, какие классы есть в библиотеке.
Информацию о любом классе можно получить с помощью дизассемблера javap.
Из результата видно, что класс содержит кроме пустого конструктора, ещё один метод sum, внутри которого в цикле вызывается метод add класса Adder. По завершении метода sum, вызывается Adder.getSum().
Без ключа -c программа выдаст только список переменных и методов (если использовать -private, то всех).
Лучше снабдить библиотеку документацией
Изменим для этого класс калькулятора.
Документацию можно создать следующей командой. При ошибке программа выдаст список возможных опций.
В результате получиться следующее
Можно подписать jar-архив
Если требуется подписать свою библиотеку цифровой подписью, на помощь придут keytool и jarsigner.
Генерируем подпись.
Генерируем Certificate Signing Request (CSR)
Содержимое полученного файла отправляем в центр сертификации. От центра сертификации получаем сертификат. Сохраняем его в файле (например, qwertokey.cer) и импортируем в хранилище
Файл qwertokey.cer отправляем всем, кто хочет проверить архив. Проверяется он так
Использование библиотеки
Есть программа HelloWorld, которая использует библиотечный класс Calculator. Чтобы скомпилировать и запустить программу, нужно присоединить библиотеку.
Компилируем
Собираем программу
Это можно сделать по-разному.
Первый способ
Здесь есть тонкости.
В строке
не должно быть пробелов в конце.
Вторая тонкость описана в [3]: в этой же строке должен стоять перенос на следующую строку. Это если манифест помещается в архив сторонним архиватором.
Программа jar не включит в манифест последнюю строку из манифеста, если в конце не стоит перенос строки.
Ещё момент: в манифесте не должно быть пустых строк между строками. Будет выдана ошибка «java.io.IOException: invalid manifest format».
При использовании команды echo надо следить только за пробелом в конце строки с main-class.
Второй способ
В данном способе избегаем ошибки с пробелом в main-class.
Третий способ
Включили код нужной библиотеки в исполняемый файл.
Запуск исполняемого jar-файла
Файл calculator.jar исполняемым не является. А вот helloworld.jar можно запустить.
Если архив был создан первыми двумя способами, то рядом с ним в одном каталоге должна находится папка lib с файлом calculator.jar. Такие ограничения из-за того, что в манифесте в class-path указан путь относительно исполняемого файла.
При использовании третьего способа нужные библиотеки включаются в исполняемый файл. Держать рядом нужные библиотеки не требуется. Запускается аналогично.
Как быть с приложениями JavaEE
Аналогично. Только библиотеки для компиляции нужно брать у сервера приложений, который используется. Если я использую JBoss, то для компиляции сервлета мне нужно будет выполнить примерно следующее
Структура архива JavaEE-приложения должна соответствовать определенному формату. Например
Способы запуска приложения на самом сервере с помощью командной строки для каждого сервера различны.
Надеюсь, данная статья станет для кого-нибудь шпаргалкой для работы с Java в командной строке. Данные навыки помогут понять содержание и смысл Ant-скриптов и ответить на собеседовании на более каверзные вопросы, чем «Какая IDE Вам больше нравится?».
Пусть исходный файл HelloUniverse.java содержит определение класса и статичный метод main , который выводит в терминал одну строку текста:
Обычно для запуска этого класса требуется сначала скомпилировать его с помощью Java-компилятора (javac), который создаст файл HelloUniverse.class:
Затем нужно с помощью команды виртуальной машины Java (интерпретатора) запустить получившийся файл:
Тогда сначала запустится виртуалка, которая загрузит класс и исполнит код.
А если вам нужно быстро проверить фрагмент кода? Или вы новичок в Java (в данном случае это ключевой момент) и хотите поэкспериментировать с языком? Описанные два этапа могут всё усложнить.
В Java SE 11 можно напрямую запускать одиночные исходные файлы без промежуточной компиляции.
Эта возможность особенно полезна для новичков, которые хотят поработать с простыми программами. В сочетании с jshell получается прекрасный набор инструментов для обучения начинающих.
Профессионалы могут с помощью этих инструментов изучать нововведения в языке или тестировать незнакомые API. На наш взгляд, лучше автоматизировать многие задачи, вроде написания Java-программ в виде скриптов с последующим исполнением из оболочки ОС. В результате мы можем гибко работать с shell-скриптами и пользоваться всеми возможностями Java. Поговорим об этом подробнее во второй части статьи.
Эта прекрасная возможность Java 11 позволяет напрямую исполнять одиночный исходный файл без компилирования. Давайте обсудим.
Что вам потребуется
Для запуска кода, приведённого в статье, вам понадобится версия Java не ниже 11. На момент написания статьи текущим релизом был Java SE Development Kit 12.0.1 — финальная версия находится здесь, достаточно принять условия лицензии и кликнуть на ссылку для вашей ОС. Если хотите поэкспериментировать с самыми свежими возможностями, то можете скачать JDK 13 early access.
Обратите внимание, что сейчас также доступны релизы OpenJDK разных вендоров, в том числе AdoptOpenJDK.
В этой статье мы будем вместо Java IDE применять обычный текстовый редактор, чтобы избежать всякой магии IDE, и использовать командную строку Java прямо в терминале.
Запускаем .java с помощью Java
Функция JEP 330 (запуск однофайловых программ с исходным кодом) появилась в JDK 11. Она позволяет напрямую исполнять исходные файлы с исходным Java-кодом, без использования интерпретатора. Исходный код компилируется в памяти, а затем исполняется интерпретатором без создания на диске .class-файла.
Однако эта функция ограничена кодом, который хранится в одном файле. Вы не можете исполнять сразу несколько исходных файлов.
Чтобы обойти это ограничение, все классы нужно определять в одном файле. Никаких ограничений на их количество нет. Кроме того, пока они находятся в одном файле, не имеет значения, являются ли они публичными или частными.
Первый класс, определённый в файле, будет считаться основным, и в него нужно поместить метод main. То есть важна очерёдность.
Первый пример
Начнём с классического простейшего примера — Hello Universe!
Мы продемонстрируем описываемую возможность на разных примерах, чтобы вы получили представление, как можно её использовать в повседневном программировании.
Создайте файл HelloUniverse.java с кодом из начала статьи, скомпилируйте и запустите получившийся class-файл. Затем удалите его, сейчас поймёте зачем:
Если теперь с помощью Java-интерпретатора вы запустите class-файл без компиляции:
то увидите тот же результат: файл будет исполнен.
То есть под капотом всё же выполняется компиляция. И в случае её ошибки мы получим уведомление об этом. Можете проверить структуру директорий и убедиться, что class-файл не генерируется, компиляция выполняется в памяти.
Теперь давайте разберёмся, как это всё устроено.
Как интерпретатор Java выполняет программу HelloUniverse
В JDK 10 модуль запуска Java может работать в трёх режимах:
- Исполнение class-файла.
- Исполнение основного класса из JAR-файла.
- Исполнение основного класса модуля.
- Исполнение класса, объявленного в исходном файле.
Система определяет ваше намерение ввести исходный файл по двум признакам:
- Первый элемент в командной строке не является ни опцией, ни частью опции.
- В строке может присутствовать опция --source .
Во втором случае выбирается режим работы с исходным файлом, и первый элемент в командной строке, который не является опцией, считается исходным файлом, который нужно скомпилировать и запустить.
Если файл не имеет расширения .java, то нужно использовать опцию --source , чтобы принудительно перейти в режим работы с исходным файлом.
Это важно в случаях, когда исходный файл представляет из себя «скрипт», который нужно выполнить, а имя файла не соответствует обычным соглашениям о наименованиях исходных файлов с Java-кодом.
С помощью опции --source можно определять версию языка исходника. Об этом мы поговорим ниже.
Можно ли передавать в командной строке аргументы?
Давайте расширим нашу программу Hello Universe, чтобы она выводила персональное приветствие любому пользователю, зашедшему на InfoQ Universe:
Сохраним код в файле Greater.java. Обратите внимание, что имя файла не соответствует имени публичного класса. Это нарушает правила спецификации Java.
Как видите, совершенно не важно, что имена класса и файла не совпадают. Внимательный читатель мог также заметить, что мы передали в код аргументы после обработки имени файла. Это означает, что любой аргумент в командной строке, идущий после имени файла, передаётся стандартному основному методу.
Определяем уровень исходного кода с помощью опции --source
Есть два сценария использования опции --source :
- Определение уровня исходного кода.
- Принудительный перевод runtime-среды Java в режим работы с исходным файлом.
Давайте сначала рассмотрим второй сценарий. Переименуем Greater.java просто в greater без расширения и попробуем выполнить:
При отсутствии расширения .java интерпретатор команд ищет скомпилированный класс по имени, переданному в виде аргумента — это первый режим работы модуля запуска Java. Чтобы это не происходило, воспользуемся опцией --source для принудительного переключения в режим работы с исходным файлом:
Теперь перейдём к первому сценарию. Класс Greater.java совместим с JDK 10, поскольку содержит ключевое слово var , но не совместим с JDK 9. Изменим source на 10 :
Снова запустим предыдущую команду, но в этот раз передадим --source 9 вместо 10 :
Обратите внимание: компилятор предупреждает о том, что var стала в JDK 10 ограниченным именем типа. Но поскольку у нас язык уровня 10, компиляция продолжается. Однако возникает сбой, потому что в исходном файле нет типа с именем var .
Всё просто. Теперь рассмотрим использование нескольких классов.
Работает ли этот подход с несколькими классами?
Рассмотрим пример с двумя классами. Код проверяет, является ли заданное строковое значение палиндромом.
Вот код, сохранённый в файле PalindromeChecker.java:
Запустим снова, подставив «RaceCar» вместо «MadAm»:
Теперь подставим «Mohamed» вместо «RaceCar»:
Как видите, можно добавлять в один исходный файл сколько угодно публичных классов. Следите только за тем, чтобы основной метод был определён первым. Интерпретатор будет использовать первый класс в качестве стартовой точки для запуска программы после компилирования кода в памяти.
Можно использовать модули?
Да, никаких ограничений. Скомпилированный в памяти код запускается как часть безымянного модуля с опцией --add-modules=ALL-DEFAULT , которая даёт доступ ко всем модулям, поставляемым с JDK.
То есть код может использовать разные модули без необходимости явно определять зависимости с помощью module-info.java.
Запустим программу и получим результат:
Теперь вы можете быстро тестировать новые фичи, предоставляемые разными модулями, не создавая свой собственный модуль.
Почему скрипты так важны в Java?
Сначала давайте вспомним, что такое скрипты:
Скрипт — это программа, написанная для определённого runtime-окружения, которая автоматизирует исполнение задач или команд, которые человек может исполнять поочерёдно.
Из этого общего определения мы можем вывести простое определение скриптового языка — это язык программирования, использующий высокоуровневые конструкции для интерпретации и исполнения по одной команде (или команд) за раз.
Скриптовый язык использует серии команд, записанных в файле. Часто такие языки являются интерпретируемыми (а не компилируемыми) и придерживающимися процедурного стиля программирования (хотя некоторые скриптовые языки также обладают свойствами объектно-ориентированных языков).
В целом скриптовые языки легче в освоении и быстрее в наборе кода по сравнению с более структурированными компилируемыми языками вроде Java, C и С++. К серверным скриптовым языкам относятся Perl, PHP и Python, а на клиентской стороне — JavaScript.
Долгое время Java считался хорошо структурированным, сильно типизированным компилируемым языком, который интерпретируется виртуальной машиной для выполнения на любой вычислительной архитектуре. Однако Java не так прост в изучении и прототипировании по сравнению с другими скриптовыми языками.
Тем не менее, Java уже исполнилось 24 года, его использует около 10 млн разработчиков по всему миру. В последних релизах добавили ряд новых возможностей, чтобы молодым программистам было легче изучать этот язык, а также чтобы пользоваться функциями языка и API без компилирования и IDE. Например, в Java SE 9 появился инструмент JShell (REPL), который поддерживает интерактивное программирование.
А с выходом JDK 11 этот язык получил возможность поддержки скриптов, поскольку теперь вы можете исполнять код с помощью простого вызова команды java !
В Java 11 есть два основных способа использования скриптов:
- Прямой вызов команды java .
- Применение *nix-скриптов для командной строки, аналогичных Bash-скриптам.
Shebang-файлы: запускаем Java как shell-скрипт
Итак, в Java SE 11 появилась поддержка скриптов, включая традиционные shebang-файлы из мира *nix. Для их поддержки не потребовалось спецификации языка.
Запустим следующий пример в терминале, работающем под macOS Mojave 10.14.5. Но сначала определим важные правила, которым нужно следовать при создании shebang-файла:
Сохраним код в файл с именем dirlist без расширения, а затем пометим его как исполняемый: mohamed_taman:code$ chmod +x dirlist .
Запустим снова с помощью команды, которая передаёт родительскую директорию, и проверим результат.
Примечание: при оценке исходного кода интерпретатор игнорирует shebang-строку (первую строку). Таким образом, shebang-файл можно явно вызвать с помощью модуля запуска, например, с дополнительными опциями:
Также нужно отметить: если скриптовый файл лежит в текущей директории, то вы можете выполнить его так:
А если скрипт лежит в директории, путь которой указан в пользовательском PATH, то выполнить его можно так:
И в завершение дам несколько советов, о чём нужно помнить при использовании скриптов.
Советы
- Некоторые опции, которые вы будете передавать в javac, могут не передаться (или не распознаться) java , например, опции -processor или -Werror .
- Если в classpath есть файлы .class и .java, то модуль запуска заставит вас использовать class-файл.
Обратите внимание на два файла java.java в пакете HelloUniverse и файл HelloUniverse.java в той же директории. Если вы попробуете выполнить:
Резюме
Начиная с Java SE 11 и впервые в истории программирования вы можете напрямую исполнять скрипты с Java-кодом без компилирования. Это позволяет писать скрипты на Java и исполнять их из *nix-командной строки.
При разработке на Spring Boot иногда нам нужно выполнить метод или фрагмент кода при запуске приложения. Этот код может быть любым, от записи определенной информации до настройки базы данных, заданий cron и т. д. Мы не можем просто поместить этот код в конструктор, потому что требуемые переменные или службы могут быть еще не инициализированы. Это может привести к null pointer исключению или некоторым другим.
Зачем нам нужно запускать код при запуске Spring Boot?
Нам нужно запускать метод при запуске приложения по многим причинам, например, для:
Обработки базы данных или файлов, индексации, создания кэшей и т. д.
Запуска фоновых процессов, таких как отправка уведомления, выборка данных из некоторой очереди и т. д.
Различные способы запуска метода после запуска Spring Boot
У каждого способа есть свои преимущества. Давайте рассмотрим подробнее, чтобы решить, что нам следует использовать:
события Spring Boot Application
аннотацию @Postconstruct для метода
атрибут инициализации аннотации @bean
1. Использование интерфейса CommandLineRunner
CommandLineRunner - это функциональный интерфейс Spring Boot, который используется для запуска кода при запуске приложения. Он находится в пакете org.springframework.boot.
В процессе запуска после инициализации контекста Spring boot вызывает свой метод run() с аргументами командной строки, предоставленными приложению.
Чтобы сообщить Spring Boot о нашем интерфейсе commandlineRunner, мы можем либо реализовать его и добавить аннотацию @Component над классом, либо создать его bean-компонент с помощью @bean.
Пример реализации интерфейса CommandLineRunner
Пример создания bean-компонента интерфейса CommandLineRunner
Мы можем запустить приложение из командной строки или IDE. Давайте рассмотрим пример, когда мы запускаем приложение с аргументами «–status = running».
Это дает следующий вывод журнала:
Как мы видим, параметр не анализируется, а вместо этого интерпретируется как одно значение «status = running».
Чтобы получить доступ к аргументам командной строки в проанализированном формате, нам нужно использовать интерфейс ApplicationRunner. Мы рассмотрим это чуть позже.
Spring Boot добавляет интерфейс CommandLineRunner в процесс запуска. Следовательно, выброшенное исключение в commandlineRunner заставит процесс загрузки Spring прервать запуск.
Мы можем создать несколько CommandLineRunner в одном приложении. Используя интерфейс Ordered или аннотацию @Order, мы можем настроить порядок, в котором они должны запускаться. Меньшее значение означает более высокий приоритет. По умолчанию все компоненты создаются с самым низким приоритетом. Поэтому компоненты не указанные конфигурации order будут вызываться последними.
Мы можем использовать аннотацию @Order, как показано ниже
2. Использование интерфейса ApplicationRunner
Как обсуждалось ранее, для доступа к анализируемым аргументам нам необходимо использовать интерфейс ApplicationRunner. Интерфейс ApplicationRunner предоставляет метод запуска с ApplicationArguments вместо необработанного массива строк.
ApplicationArguments - это интерфейс, который доступен из srping boot 1.3 в пакете org.springframework.boot.
Он предоставляет различные способы доступа к аргументам, как показано ниже.
Предоставляет необработанные аргументы, которые были переданы приложению
Именам всех необязательных аргументов предшествует «-», например: –name = «stacktrace»
Возвращает необработанные необязательные аргументы. Аргументы без «-»
boolean containsOption(String name)
Проверяет, присутствует ли имя в необязательных аргументах или нет
List getOptionValues(String name)
Предоставляет значение аргумента по имени
Метод getOptionValues возвращает список значений, потому что значение аргумента может быть массивом, поскольку мы можем использовать один и тот же ключ более одного раза в командной строке.
Например, –name = “stacktrace” - Port = 8080 –name = ”guru”.
Пример реализации интерфейса Application runner
Давайте запустим приведенную ниже программу, используя аргументы «status = running –mood = happy 10–20», и давайте разберемся с результатом.
CommandLineRunner и ApplicationRunner имеют схожие функции, например:
Исключение в методе run() прервет запуск приложения.
Несколько ApplicationRunner можно заказать с помощью упорядоченного интерфейса или аннотации @Order.
Важнее всего отметить, что порядок разделяется между CommandLineRunners и ApplicationRunners. Это означает, что порядок выполнения может быть смешанным между commandlineRunner и applicationRunner.
3. Событие приложения в Spring Boot
Фреймворк Spring запускает разные события в разных ситуациях. Он также вызывает множество событий в процессе запуска. Мы можем использовать эти события для выполнения нашего кода, например, ApplicationReadyEvent можно использовать для выполнения кода после запуска приложения загрузки Spring.
Если нам не нужны аргументы командной строки, это лучший способ выполнить код после запуска приложения.
Некоторые наиболее важные события spring boot,
ApplicationContextInitializedEvent: запускается после подготовки ApplicationContext и вызова ApplicationContextInitializers, но до загрузки определений bean-компонентов
ApplicationPreparedEvent: запускается после загрузки определений bean-компонентов
ApplicationStartedEvent: запускается после обновления контекста, но до вызова командной строки и запуска приложений.
ApplicationReadyEvent: запускается после вызова любого приложения и запуска командной строки
ApplicationFailedEvent: срабатывает, если есть исключение при запуске
Можно создать несколько ApplicationListeners. Их можно упорядочивать с помощью аннотации @Order или с помощью интерфейса Ordered.
Order используется совместно с другими ApplicationListeners того же типа, но не с ApplicationRunners или CommandLineRunners.
4. Аннотация метода @Postconstruct
Метод можно пометить аннотацией @PostConstruct. Всякий раз, когда метод отмечен этой аннотацией, он будет вызываться сразу после внедрения зависимости.
Метод @PostConstruct связан с конкретным классом, поэтому его следует использовать только для кода конкретного класса. В каждом классе может быть только один метод с аннотацией postConstruct.
Следует отметить, что, если класс помечен как lazy, это означает, что класс создается по запросу. После этого будет выполнен метод, помеченный аннотацией @postConstruct.
Метод, отмеченный аннотацией postConstruct, может иметь любое имя, но не должен иметь никаких параметров. Он должен быть void и не должен быть static.
Обратите внимание, что аннотация @postConstruct является частью модуля Java EE и помечена как устаревшая в Java 9 и удалена в Java 11. Мы все еще можем использовать ее, добавив java.se.ee в приложение.
5. Интерфейс InitializingBean
Решение InitializingBean работает точно так же, как аннотация postConstruct. Вместо использования аннотации мы должны реализовать интерфейс InitializingBean. Затем нам нужно переопределить метод void afterPropertiesSet().
InitializingBean является частью пакета org.springframework.beans.factory.
Вы можете подумать, что же произойдет, если мы будем использовать одновременно аннотацию @PostConstruct и InitializingBean. В этом случае метод @PostConstruct будет вызываться перед методом afterPropertiesSet() InitializingBean.
6. Атрибут Init аннотации @bean
Мы можем реализовать метод, используя свойство initMethod в аннотации @Bean. Этот метод будет вызываться после инициализации bean-компонента.
Метод, предоставленный в initMethod, должен быть void и не иметь аргументов. Этот метод может быть даже private.
Если у вас есть реализация InitializingBean и свойство initMethod аннотации @Bean для того же класса, то метод afterPropertiesSet для InitializingBean будет вызываться перед initMethod.
Сочетание разных подходов
Наконец, иногда нам может потребоваться объединить несколько вариантов. При этом они будут выполняться в следующем порядке:
Метод инициализации Bean-компонента
ApplicationRunner или CommandLineRunner в зависимости от порядка
Краткий обзор
Есть разные способы запустить код после запуска Spring Boot приложения
Мы можем использовать CommandLineRunner или ApplicationRunner Interface.
Используйте интерфейс ApplicationRunner для доступа к анализируемым аргументам вместо массива необработанных строк
Событие загрузки Spring выполняет код при запуске приложения
Метод, отмеченный аннотацией @PostConstruct, выполняется после инициализации объекта
Метод afterPropertiesSet() интерфейса InitializingBean вызывается после инициализации объекта.
В аннотации @Bean есть атрибут «initMethod» для предоставления метода, который будет вызываться после инициализации bean-компонента.
Как правило, каждое значимое приложение включает в себя один или несколько файлов JAR в качестве зависимостей. Однако бывают случаи, когда сам файл JAR представляет собой автономное приложение или веб-приложение.
В этой статье мы сосредоточимся на сценарии автономного приложения. В дальнейшем мы будем называть его приложением JAR.
В этом уроке мы сначала узнаем, как создать приложение JAR. Позже мы узнаем, как запускать приложение JAR с аргументами командной строки или без них|/.
2. Создайте приложение JAR
Файл JAR может содержать один или несколько основных классов. Каждый основной класс является точкой входа приложения . Таким образом, теоретически файл JAR может содержать более одного приложения, но он должен содержать по крайней мере один основной класс, чтобы иметь возможность работать.
Файл JAR может иметь одну точку входа, установленную в файле манифеста . В этом случае файл JAR является исполняемым файлом JAR . Основной класс должен быть включен в этот файл JAR.
Прежде всего, давайте рассмотрим краткий пример того, как скомпилировать наши классы и создать исполняемый файл JAR с файлом манифеста:
Неисполняемый JAR-это просто файл JAR, который не имеет Основного класса , определенного в файле манифеста. Как мы увидим позже, мы все еще можем запустить основной класс, который содержится в самом файле JAR.
Вот как мы создадим неисполняемую банку без файла манифеста:
3. Аргументы командной строки Java
Как и любое приложение, приложение JAR принимает любое количество аргументов, включая нулевые аргументы. Все зависит от потребностей приложения.
Это позволяет пользователю указать информацию о конфигурации при запуске приложения .
В результате приложение может избежать жестко закодированных значений и по-прежнему может обрабатывать множество различных вариантов использования.
Аргумент может содержать любые буквенно-цифровые символы, символы юникода и, возможно, некоторые специальные символы, разрешенные оболочкой, например”@”.
Аргументы разделяются одним или несколькими пробелами . Если аргумент должен содержать пробелы, они должны быть заключены между кавычками. Одинарные или двойные кавычки работают нормально.
Обычно для типичного приложения Java при вызове приложения пользователь вводит аргументы командной строки после имени класса.
Однако это не всегда относится к приложениям JAR.
Как мы уже обсуждали, точкой входа основного класса Java является метод main . Все аргументы являются String s и передаются в основной метод в виде массива String .
Тем не менее, внутри приложения мы можем преобразовать любой элемент массива String в другие типы данных, такие как char , int , double , их классы-оболочки, или другие соответствующие типы.
4. Запустите исполняемый файл JAR с аргументами
Давайте рассмотрим базовый синтаксис для запуска исполняемого файла JAR с аргументами:
java -jar jar-имя файла [args …]
Исполняемый файл JAR, созданный ранее, представляет собой простое приложение, которое просто выводит переданные аргументы. Мы можем запустить его с любым количеством аргументов. Ниже приведен пример с двумя аргументами:
Мы увидим следующий вывод в консоли:
Таким образом, при вызове исполняемого файла JAR нам не нужно указывать имя основного класса в командной строке . Мы просто добавляем наши аргументы после имени файла JAR. Если мы указываем имя класса после имени исполняемого файла JAR, оно просто становится первым аргументом для фактического основного класса.
В большинстве случаев приложение JAR-это исполняемый файл JAR. Исполняемый файл JAR может содержать не более одного основного класса, определенного в файле манифеста .
Следовательно, другие приложения в том же исполняемом файле JAR не могут быть установлены в файле манифеста, но мы все равно можем запускать их из командной строки, как и для неисполняемого файла JAR. Как именно, мы увидим в следующем разделе.
5. Запустите неисполняемую банку с аргументами
Чтобы запустить приложение в неисполняемом файле JAR, мы должны использовать опцию -cp вместо -jar . Мы будем использовать параметр -cp (сокращение от classpath), чтобы указать файл JAR, содержащий файл класса, который мы хотим выполнить:
java -cp jar-file-name main-class-name [args …]
Как вы можете видеть, в этом случае нам придется включить имя основного класса в командную строку, за которым следуют аргументы .
Неисполняемый JAR, созданный ранее, содержит то же самое простое приложение. Мы можем бежать
Неисполняемый JAR, созданный ранее, содержит то же самое простое приложение. Мы можем бежать
Неисполняемый JAR, созданный ранее, содержит то же самое простое приложение. Мы можем бежать
В этом уроке мы изучили два способа запуска приложения JAR в командной строке с аргументами или без них.
Мы также продемонстрировали, что аргумент может содержать пробелы и специальные символы (если это разрешено оболочкой).
Читайте также: