Не совсем кастомизируем. Мы его своим API оборачиваем, чтобы проще было с ним работать. И чтобы всем было проще мигрировать приложения на новые версии платформы. Если посмотрите на примеры — там не совсем Vaadin в контроллерах. А чего от Vaadin не отнять — так это компонентов, с которыми очень быстро можно делать GUI.
А ещё можем TypeScript SDK генерировать :-) Полимер и Swing переведем в mainteinance mode, на них не так много запросов. А вот TypeScript будем и дальше развивать для тех, кому нужен кастомный Front-End.
Вот про reflection как грязный хак — даже не знаю. Такой философский вопрос, заслуживающий отдельного монументального труда. Эта возможность есть же не только в Java. Например, C# появился позже, а в нем есть Reflection. Не думаю, что это там оставили, только чтобы программистов с Java перетащить :-)
В итоге получилось в среднем 3.7 и 2.7 секунды при старте именно приложения. И в случае, когда используется ленивая инициализация бинов, в логах интересная, но ожидаемая картинка:
Started WebApplication in 2.707 seconds (JVM running for 5.198)
HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
HHH000490: Using JtaPlatform implementation: [o.h.e.t.j.p.internal.NoJtaPlatform]
Initialized JPA EntityManagerFactory for persistence unit 'default'
Значит, Vert.x отлично ложится на привычные абстракции, который есть у вас в голове :-) Но есть же люди, которые думают не совсем так, как вы, а как разработчики Quarkus. И им, может быть, невыносимо неудобно пользоваться vert.x, а quarkus зайдет отлично :-)
Кому-то нравится писать hello world так:
public class Server extends AbstractVerticle {
public void start() {
vertx.createHttpServer().requestHandler(req -> {
req.response()
.putHeader("content-type", "text/plain")
.end("Hello from Vert.x!");
}).listen(8080);
}
а кому-то — так:
@Path("/hello")
public class GreetingResource {
@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
return "hello from quarkus";
}
}
Spring Boot — это катапульт-фреймворк? Он тоже позволяет быстро клепать приложения для backend и не прописывать явные зависимости. Однако, в его случае, похоже, польза от применения перевешивает жуткость головной боли. Судя по всему, quarkus, да и micronaut идут по тому же пути, как spring boot. На мой взгляд, они довольно расширяемы, и, как мне кажется, в 90% случаев их стандартной функциональности достаточно для разработки разных видов приложений (у Quarkus, конечно, меньше всяких расширений сейчас). А экономим мы усилия по написанию всякого сервисного кода и сдруживанию разных зависимостей, которые не всегда можно быстро сдружить.
Конечно, сложно предугадать, выстрелит фреймворк или нет. Много факторов: привычность/удобство использования, стабильность, поддержка, скорость развития, количество интеграций, сообщество. Посмотрим, что получится с Quarkus. Что меня привлекает — они полагаются на существующие фреймворки, просто убирают boilerplate. А так, если до этого вы использовали Hibernate/JAX-RS/CDI, то переезд на quarkus не должен занять много времени.
На мой взгляд — идеологически они сильно похожи. На micronaut я не писал сколько-нибудь масштабный и сложных проектов, поэтому мне сложно сейчас сложно рассуждать о плюсах и минусах этих фреймворков. Явное отличие — в Quarkus нет Application.java :-)
Так берешь Truffle и строишь AST из C# — и будут программы, написанные на C# запускаться :-) Можно ещё попробовать CIL напрямую подсовывать в GraalVM, но это посложнее.
Там как раз написано, что bitcode может выполняться совместно с python. Но совсем нативные образы не получится слинковать, мне кажется. Но, если библиотеки перекомпилировать, то должно все получиться.
Это не совсем магия. При перекладывании данных из формочки в базу и обратно, вы, скорее всего, ЯВНО с этим не встретитесь. Но если вы пишете фреймворк, то рано или поздно столкнетесь с необходимостью использовать reflection, например. Reflection — магия? А если захотите, чтобы фреймворк работал ещё быстрее, то будете искать варианты, как ускорить reflection. И придете к MethodHandle, лямбдам и вот этому вот всему. В рамках формата перевода много от себя не напишешь, можно почитать пример тут, если не страшно :-) А ещё можно глянуть в исходники одного из классов библиотеки spring-data-commons — ClassGeneratingPropertyAccessorFactory, там тоже есть чему порадоваться. А этим кодом многие люди пользуются и он как-то поддерживается.
Самовыражаться в коде боевого проекта — вообще плохая идея :-) А хаки, трюки и хитрости должны быть локализованы и подробно задокументированы, иногда без них нельзя. А ещё, некоторые задачи нельзя передавать недостаточно опытным разработчикам, если они недостаточно четко понимают, как оно внутри работает, как бы оскорбительно это не звучало. Пока разработчик не понимает, зачем нужен synchronized, отдавать ему код по многопоточной обработке данных не надо.
Эта статья не совсем про лямбды в целом, а про отдельные вещи, которые нужны в ограниченном наборе случаев. Посколькую мы пишем фреймворк, то есть места, где использование способов, описанных в статье, помогает значительно улучшить производительность. Эта задача решатеся при помощи Reflection API без лямбд, но это значительно медленнее.
Лично меня не сильно пугает синтаксис стримов, если аккуратно писать — то все читаемо получается. И стримы не сложнее «понятного человеку» кода. До Java 8, лямбд и стримов я видел примеры нечитаемого кода. Как обычно — все сводится к тому, как человек пишет.
На coursera есть курс Kotlin for Java developers там задачка про таксопарк. Так вот, там, если решать с использованием стримов — то все получается очень красиво. Если решать в более «императивном» стиле — то кода будет в три раза больше, мне кажется :-)
Это пример кода, который показывает потенциальные проблемы использования лямбд. Это не фрагмент кода CUBA :-)
А проблема читабельности кода Java после введения лямбда-выражений в 8-ке — это отдельная тема, достойная большой статьи. Если этими вещами злоупотреблять — то получится страшное.
Просто заметка — у так назывемых «внутренних» циклов, есть одно преимущество — можно поставить .parallelStream
и обрабатывать коллекцию в несколько потоков. Но, конечно, это тоже можно превратить в недостаток, если пихать параллельность бездумно :-) Тут хорошо написано про то, что стримы могут код замедлять в 5 раз.
spring.jpa.hibernate.ddl-auto = none
spring.data.jpa.repositories.bootstrap-mode = lazy
В итоге получилось в среднем 3.7 и 2.7 секунды при старте именно приложения. И в случае, когда используется ленивая инициализация бинов, в логах интересная, но ожидаемая картинка:
Started WebApplication in 2.707 seconds (JVM running for 5.198)
HCANN000001: Hibernate Commons Annotations {5.1.0.Final}
HHH000400: Using dialect: org.hibernate.dialect.H2Dialect
HHH000490: Using JtaPlatform implementation: [o.h.e.t.j.p.internal.NoJtaPlatform]
Initialized JPA EntityManagerFactory for persistence unit 'default'
Кому-то нравится писать hello world так:
а кому-то — так:
На coursera есть курс Kotlin for Java developers там задачка про таксопарк. Так вот, там, если решать с использованием стримов — то все получается очень красиво. Если решать в более «императивном» стиле — то кода будет в три раза больше, мне кажется :-)
А проблема читабельности кода Java после введения лямбда-выражений в 8-ке — это отдельная тема, достойная большой статьи. Если этими вещами злоупотреблять — то получится страшное.
Просто заметка — у так назывемых «внутренних» циклов, есть одно преимущество — можно поставить
.parallelStream
и обрабатывать коллекцию в несколько потоков. Но, конечно, это тоже можно превратить в недостаток, если пихать параллельность бездумно :-) Тут хорошо написано про то, что стримы могут код замедлять в 5 раз.
Вот мой код. Это нормально работает, если запускать init в пустой директории.