Web приложение на Java без фреймворков

в 12:57, , рубрики: java, метки:

Привет!
Меня зовут Евгений, я программирую на 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 без фреймворов, исключительно для получения небольшого опыта и знаний.

В чем смысл
Давайте вспомним, чем отличается фреймворк от библиотеки? В первую очередь тем, что он даем вашему приложению некий жизненный цикл, изменить и контролировать который иногда становится очень сложно. Если вы построите приложения без фреймворков — у вас будут безграничные возможности контроля и расширения своего приложения.

С чего начать?
Для начала, давайте определим, что нам вообще надо, для того что бы создать веб-приложение.

Нам нужны:

  1. База данных (Во время разработки я использую базу данных H2, так как её не нужно устанавливать, и её синтаксис очень совместим с MySQL, на который я перейду когда закончу разработку продукта).
  2. API для работы с БД. Я решил использовать JDBI.
  3. Шаблонизатор для построения web-страниц. Мой выбор пал на FreeMarker. Его очень легко настраивать, и так же он имеет очень большую и гибкую функциональность.
  4. Веб сервер. Собственно для обработки запросов от браузеров. Я выбрал Jetty Embeded, он достаточно компактный и имеет хороший функционал. Да, он тянет за собой Servlet-ы из Java EE, но в минимальном наборе.
  5. Тестирование. Я использую классический стек 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

В следующих уроках мы рассмотрим структуру проекта и сделаем первый контроллер на этом стеке технологий.

П. С. ребят, это мой первый урок, если что-то не нравится — пожалуйста напишите мне об этом в личном сообщении, или оставьте комментарий.

Автор: Лунтик

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js