Привет!
Меня зовут Евгений, я программирую на Java примерно 7 лет, и я хочу начать цикл уроков о том, как же можно жить и писать веб приложения на Java без фреймворков вроде Spring Framework, или Play Framework, и когда и почему это стоит делать. Цикл будет иметь имя iBoard, так как я буду показывать реальные примеры на продукте iBoard — доска объявлений. В уроке мы рассмотрим, как построить хорошую архитектуру для такого приложения, рассмотрим не стандартный стек для разработки такого приложения, и сравним, что же лучше, Java EE с фреймворками или Java SE с библиотеками.
Хочу сказать сразу, я не заставляю кого-либо отказываться от фреймворков, и спорить что лучше. Обязательно осознайте это, что бы не разгорались холивары по поводу выбора технологий/фреймворков и т д.
Почему без фреймворков?
Давайте рассмотрим пример с Spring Framework.
Для начала, давайте разберем, почему Spring Framework это плохо. Для начала, хочу сказать, что в целом Spring Framework достаточно хороший и не плохой фреймворк, но у него есть ряд недостатков, которые заставляют разработчиков писать плохой код. В большей части, это связано с тем, что большинство фреймворков пишутся под стандарты Java EE, что бы быть максимально совместимы с различными технологиями из этого стека. Но в реальном мире, Java EE Вам не нужен в принципе.
Кто бы что не говорил, но используя спринг у себя на проекте, вы рано или поздно столкнетесь с тем, что у Вас в коде шума будет больше чем бизнес логики. Даже если Вы будете использовать Spring Boot, и все последние «нововведения» спринга — Вам всё равно придется писать код, который не связан с бизнесс-логкий вашего проекта, но связан со спрингом. Это есть шум. Взгляните на любой спринг-проект и первое что вы увидите, это будет различные Config, Factory, Adapter, Convertor, Repositroy, Dao, Mapper, Handler классы, которые никак не задействованы с бизнесом, и служат лишь для правильной настройки Spring-фреймворка. Это чревато тем, что с ростом проекта, количество этого мусора будет только расти, и управлять таким проектом и конфигурировать его будет крайне тяжело.
Спринг — избыточно гибкий фреймворк, который пытается решить множество проблем, в частности проблему интеграции разных систем, но в реальной же жизни, проекты используют не так много этих же систем. И из всей функциональности, что вам предоставляет спринг — скорее всего вы используете процентов 10-20%.
Старая концепция веб-приложений
Старая концепция изначально выглядит странной, когда вы собираете веб-приложение в war файл и загружаете его на сервер приложений. То есть сервер приложений является неким контейнером, в котором работают ваши приложения. Это реально странно, ибо в современных реалиях вам приходится подымать одно и то же приложения на разных серверах. Лично меня такая концепция не устраивает. Для меня вообще выглядит странным то, что для запуска приложения я должен деплоить его в какой-то сервер и уже сервер будет его подымать. Потому что как минимум у меня добавляется ещё одна задача — заботится о этом сервере.
Почему я должен отказываться от фреймворков
Я не заставляю никого отказываться от какого-либо фреймворка. Урок предназначен лишь для тех, кто никогда не пробовал разрабатывать веб-приложения или веб-сайты на java без фреймворов, исключительно для получения небольшого опыта и знаний.
В чем смысл
Давайте вспомним, чем отличается фреймворк от библиотеки? В первую очередь тем, что он даем вашему приложению некий жизненный цикл, изменить и контролировать который иногда становится очень сложно. Если вы построите приложения без фреймворков — у вас будут безграничные возможности контроля и расширения своего приложения.
С чего начать?
Для начала, давайте определим, что нам вообще надо, для того что бы создать веб-приложение.
Нам нужны:
- База данных (Во время разработки я использую базу данных H2, так как её не нужно устанавливать, и её синтаксис очень совместим с MySQL, на который я перейду когда закончу разработку продукта).
- API для работы с БД. Я решил использовать JDBI.
- Шаблонизатор для построения web-страниц. Мой выбор пал на FreeMarker. Его очень легко настраивать, и так же он имеет очень большую и гибкую функциональность.
- Веб сервер. Собственно для обработки запросов от браузеров. Я выбрал Jetty Embeded, он достаточно компактный и имеет хороший функционал. Да, он тянет за собой Servlet-ы из Java EE, но в минимальном наборе.
- Тестирование. Я использую классический стек JUnit+Mockito.
Собственно больше ничего нам и не надо.
Для сборки проекта используется Maven. Почему именно Maven, а не к примеру Gradle? Потому что он работает намного быстрее чем Gradle, и любая IDE может без проблем интегрироваться с ним.
Вот как выглядит мой pom.xml в начале разработки проекта:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ua.iboard</groupId>
<artifactId>server</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>9.4.6.v20170531</version>
</dependency>
<dependency>
<groupId>org.jdbi</groupId>
<artifactId>jdbi</artifactId>
<version>2.78</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.23</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.196</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.8.47</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Это не «категорический» стек, по сути вы можете выбрать те библиотеки, которые нравятся вам.
Вот некоторые альтернативы:
JDBI: jOOQ, commons-dbutils, jcabi.jdbc
FreeMarker: Velocity, Thymeleaf
Jetty: Tomcat, NanoHttpD
В следующих уроках мы рассмотрим структуру проекта и сделаем первый контроллер на этом стеке технологий.
П. С. ребят, это мой первый урок, если что-то не нравится — пожалуйста напишите мне об этом в личном сообщении, или оставьте комментарий.
Автор: Лунтик