Java for Beginner
742 subscribers
708 photos
196 videos
12 files
1.14K links
Канал от новичков для новичков!
Изучайте Java вместе с нами!
Здесь мы обмениваемся опытом и постоянно изучаем что-то новое!

Наш YouTube канал - https://www.youtube.com/@Java_Beginner-Dev

Наш канал на RUTube - https://rutube.ru/channel/37896292/
Download Telegram
Вопрос с собеседований

Что такое байт-код?🤓

Ответ:

Байт-код
— это промежуточное представление Java-программы после компиляции.

Он не зависит от платформы и исполняется JVM. Это позволяет запускать один и тот же код на разных ОС, не меняя программу.

Байт-код лежит в .class файлах, создаваемых компилятором javac.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
🗓 История IT-технологий сегодня — 25 сентября


ℹ️ Кто родился в этот день

Алексе́й Андре́евич Ляпуно́в (25 сентября [8 октября] 1911, Москва — 23 июня 1973, Москва) — советский математик, один из основоположников кибернетики; работал над теоретическими вопросами программирования, математической логикой и математической лингвистикой.

Серге́й Влади́мирович Русако́в (род. 25 сентября 1954, Молотов) — советский/российский математик и профессор, заведующий кафедрой прикладной математики и информатики; лидер направления «моделирование, анализ и управление сложными динамическими системами».

Уильям Даниэль «Дэнни» Хиллис (англ. William Daniel "Danny" Hillis, родился 25 сентября 1956) — американский учёный, инженер и предприниматель, пионер параллельных компьютеров, основатель Thinking Machines Corporation; внёс значительный вклад в аппаратные и программные подходы к параллелизму.


🌐 Знаковые события

1906 — испанский математик и инженер Леонардо Торрес-и-Кеведо продемонстрировал одно из первых в мире радиоуправляемых устройств — «Telekino».


#Biography #Birth_Date #Events #25Сентября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Основы ООП в Java

Глава 7. Принципы проектирования и хорошего кода

Композиция vs Наследование

В объектно-ориентированном программировании композиция и наследование — это два способа организации кода для повторного использования и связи между классами. Они решают разные задачи и подходят для разных ситуаций.

Наследование:
Механизм, при котором класс (подкласс) наследует поля, методы и поведение от другого класса (суперкласса) с помощью ключевого слова extends. Это воплощает отношение "является" (is-a). Например, Dog является Animal.

Композиция:
Механизм, при котором класс содержит объекты других классов как поля, используя их функциональность. Это воплощает отношение "имеет" (has-a). Например, Car имеет Engine.

Оба подхода позволяют повторно использовать код, но их применение влияет на гибкость, читаемость и масштабируемость программы.



Наследование: Когда использовать и проблемы

Наследование удобно, когда классы имеют четкое отношение "является", и подкласс естественным образом расширяет поведение суперкласса.

Пример наследования:
public class Animal {
protected String name;

public Animal(String name) {
this.name = name;
}

public void makeSound() {
System.out.println(name + " издает звук.");
}
}

public class Dog extends Animal {
public Dog(String name) {
super(name);
}

@Override
public void makeSound() {
System.out.println(name + " лает: Гав!");
}
}


Когда использовать:
Есть четкое is-a отношение: Dog — это Animal.
Нужно переопределить или расширить поведение (через override).
Полиморфизм: Работа с подклассами через ссылку на суперкласс (Animal[] animals).


Преимущества:
Простота: Код автоматически наследуется.
Полиморфизм: Легко реализовать через override.
Иерархия: Удобно для моделирования реальных сущностей (например, Животное → Млекопитающее → Собака).


Недостатки:
Жесткая связь: Подкласс привязан к суперклассу — изменения в суперклассе могут сломать подклассы.
Хрупкий базовый класс: Изменение метода в суперклассе может неожиданно повлиять на подклассы.
Ограничение Java: Только одиночное наследование (один extends).
Сложность в глубоких иерархиях: Много уровней наследования трудно поддерживать.
Нарушение инкапсуляции: Подклассы могут зависеть от внутренней реализации.

Пример проблемы: Если добавить метод в Animal, который не подходит для всех подклассов (например, fly()), подклассы вроде Dog окажутся в неудобном положении.


Композиция: Когда использовать и преимущества

Композиция — это включение объектов других классов как полей, чтобы использовать их функциональность. Это отношения, где класс владеет компонентами.


Пример композиции:
public class Engine {
private int horsepower;

public Engine(int horsepower) {
this.horsepower = horsepower;
}

public void start() {
System.out.println("Двигатель с " + horsepower + " л.с. запущен.");
}
}

public class Car {
private String model;
private Engine engine; // Композиция: Car "имеет" Engine

public Car(String model, Engine engine) {
this.model = model;
this.engine = engine;
}

public void drive() {
engine.start();
System.out.println(model + " едет.");
}
}


Использование:
public class Main {
public static void main(String[] args) {
Engine engine = new Engine(200);
Car car = new Car("Toyota", engine);
car.drive(); // Двигатель с 200 л.с. запущен. Toyota едет.
}
}


Когда использовать:
Отношения: Car имеет Engine, а не является им.
Нужно гибкое сочетание функциональности без жесткой связи.
Требуется заменяемость компонентов (например, разные двигатели).


Преимущества:
Гибкость: Легко заменить компонент (например, Engine на ElectricEngine).
Слабая связь: Изменения в Engine не ломают Car, если интерфейс сохранен.
Инкапсуляция: Car скрывает детали Engine, управляя доступом.
Модульность: Компоненты можно использовать в других классах.
Тестирование: Легче подменять компоненты (mocking) для тестов.


#Java #для_новичков #beginner #OOP #Composition #Extends
👍4
Недостатки:
Больше кода: Нужно явно создавать и передавать компоненты.
Сложнее полиморфизм: Требуются интерфейсы для единообразия.



Композиция vs Наследование: Как выбирать

Выбирайте композицию, если:
Нет четкого is-a отношения, а скорее has-a.
Нужна гибкость: Компоненты могут меняться (например, разные реализации Engine).
Хотите избежать жесткой связи или хрупкого базового класса.
Нужно реализовать поведение, которое не должно быть частью иерархии.

Выбирайте наследование, если:
Есть четкое is-a отношение, и подкласс логично расширяет суперкласс.
Нужен полиморфизм через ссылки на суперкласс.
Иерархия простая (1-2 уровня).


Пример: Композиция вместо наследования:

Наследование (проблема):
public class Vehicle {
public void move() {
System.out.println("Движется с помощью двигателя.");
}
}

public class Car extends Vehicle {
// Проблема: А если электромобиль или велосипед?
}

Композиция (решение):
public interface Movable {
void move();
}

public class EngineMovable implements Movable {
@Override
public void move() {
System.out.println("Движется с помощью двигателя.");
}
}

public class Car {
private Movable movement;

public Car(Movable movement) {
this.movement = movement;
}

public void drive() {
movement.move();
}
}

Теперь Car может использовать любой Movable (двигатель, электромотор), без привязки к иерархии.


Все нюансы

Наследование:
Жесткая связь: Подкласс зависит от реализации суперкласса.
Проблема ромба: В Java избежана (одиночное наследование), но множественное через интерфейсы.
Нюанс: Переопределение может нарушить контракт (Liskov Substitution Principle).


Композиция:
Требует интерфейсов для полиморфизма (например, Movable).
Нюанс: Больше кода для передачи компонентов (конструктор, сеттеры).
Делегирование: Car вызывает методы Engine — это нормально.


Когда комбинировать:
Используйте наследование для базовой структуры, композицию для поведения.
Пример: extends AbstractVehicle, но Engine как поле.


Ошибки:
Наследование вместо композиции: Глубокие иерархии или неподходящие is-a.
Композиция без интерфейсов: Теряется полиморфизм.


Дизайн:
Композиция соответствует принципу KISS (меньше связей).
Наследование — YAGNI: Не создавайте иерархии "на будущее".
DRY: Оба подхода помогают повторно использовать код.


Java-специфика:
Интерфейсы + default методы часто заменяют наследование.
Dependency Injection (Spring) — пример композиции.



Как создать это в IntelliJ IDEA

Композиция: Создайте интерфейс (New → Interface), класс с полем и методами.
Наследование: New → Class, укажите extends, IDE поможет override.
Рефакторинг: Extract Interface для перехода от наследования к композиции.



Полезные советы для новичков

Композиция по умолчанию: Если сомневаетесь, начните с has-a.
Проверяйте is-a: Dog is-an Animal? Да. Car is-an Engine? Нет.
Интерфейсы для гибкости: Комбинируйте композицию с интерфейсами.
Избегайте глубоких иерархий: Не больше 2-3 уровней.



#Java #для_новичков #beginner #OOP #Composition #Extends
👍4
Просто хочу понять сколько подписчиков из общего количества читает посты. Прочитал - нажми че-нибудь уже ☺️
Anonymous Poll
58%
✌️
29%
🎶
26%
👋
👍1
Что выведет код?

import java.util.function.Function;

public class Task250925 {
public static void main(String[] args) {
Function<Integer, Integer> plus5 = x -> x + 5;
Function<Integer, Integer> times2 = x -> x * 2;

Function<Integer, Integer> composed = plus5.compose(times2);
System.out.println(composed.apply(3));
}
}


#Tasks
👍3
Варианты ответа:
Anonymous Quiz
11%
6
11%
8
42%
11
37%
16
👍3
Создал канал в сетке!

Присоединяйтесь! 🙂

https://set.ki/channel/35sLVoe
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Вопрос с собеседований

Что такое String Pool?🤓

Ответ:

String Pool
— это область памяти, где JVM хранит уникальные строковые литералы.

Если создать строку через "abc", то повторное использование этой же строки вернёт ссылку на уже существующий объект.

Это экономит память и ускоряет сравнение строк.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
🗓 История IT-технологий сегодня — 26 сентября


ℹ️ Кто родился в этот день

Владимир Иосифович Гурман (26 сентября 1934, Москва — 8 июня 2016, Переславль-Залесский) — советский/российский учёный, специалист в области оптимального управления и разработок алгоритмов для систем управления; главный научный сотрудник Института программных систем РАН.

Влади́мир Никано́рович Реме́сленников (26 сентября 1938, Ишим, Тюменская область, СССР — 13 мая 2025, Омск, Россия) — советский/российский математик, занимался алгоритмами и компьютерной поддержкой исследований в теории групп; работал над системой «Magnus» — системой компьютерной поддержки исследований в алгебре групп.

Кристель Байер (родилась 26 сентября 1965 г.) — немецкий теоретик компьютерных наук; известна работами по моделям проверки (model checking), временной логике и автоматам.

Илкка Туоми (родился 26 сентября 1958 года) — финский исследователь интернета и теории открытых инноваций; автор статей по эволюции открытого программного обеспечения и роли интернет-инноваций.


🌐 Знаковые события

1983 Ложное срабатывание системы «Око» и решение Станислава Петрова.
В ночь на 26 сентября система предупреждения о ракетном нападении «Око» сигнализировала о запуске американских межконтинентальных баллистических ракет. Оперативным дежурным заявил, что это ложная тревога — именно этот шаг мог предотвратить ядерную войну.


2003 — остановлена работа Нупедии, предшественника Википедии.


#Biography #Birth_Date #Events #26Сентября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Реактивное программирование

Концепции реактивного программирования: Backpressure — что делать, если данных слишком много


Представьте: источник данных — как бурная река, а ваш подписчик — маленькая лодка. Если вода хлынет слишком быстро в лодку, она утонет.
Здесь на помощь приходит backpressure (обратное давление) — механизм, который позволяет подписчику контролировать скорость потока, говоря "дай мне столько, сколько я могу переварить". И это не просто тормоз, а умный регулятор, который предотвращает перегрузки и делает реактивные системы устойчивыми под любой нагрузкой.


Backpressure — ключевая фишка реактивного программирования, которая отличает его от традиционных подходов. В старых моделях (как потоки или Future) вы либо блокируете всё, либо тонете в очередях данных, рискуя исчерпать память или CPU. Здесь же контроль у потребителя: он решает, когда и сколько брать. Это решает проблемы callback-ада и блокировок, позволяя строить масштабируемые приложения — от мобильных до облачных кластеров.


Что такое backpressure и почему оно нужно?

Обратное давление — это способ, при котором получатель данных сигнализирует источнику: "замедлись, если я не успеваю". В реактивном мире данные передаются асинхронно, но без контроля это может привести к проблемам: если издатель генерирует 1 млн элементов в секунду, а подписчик обрабатывает только 100, буфер переполнится, и приложение упадёт с ошибкой "израсходована память" (OutOfMemoryError).

Backpressure вводит "обратную связь": подписчик запрашивает элементы порциями, а издатель выдаёт ровно столько.


Это встроено в Reactive Streams: в методе onSubscribe подписчик получает Subscription и использует request(long n) — "запроси n элементов". Если не запросить — данные не потекут. Это как шлюзы на реке: открываешь по мере нужды, избегая наводнения. В отличие от pull-модели (где вы тянете всё сразу), здесь баланс: push для динамики, но с контролем.

Пример базового использования в Flux (поток для множества элементов):
import reactor.core.publisher.Flux;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;

Flux<Integer> fastPublisher = Flux.range(1, 1000); // Быстрый источник: 1000 элементов

fastPublisher.subscribe(new Subscriber<Integer>() {
private Subscription sub;

@Override
public void onSubscribe(Subscription s) {
sub = s;
sub.request(5); // Сначала запрашиваем 5 элементов
}

@Override
public void onNext(Integer item) {
System.out.println("Обработано: " + item);
// Симулируем медленную обработку: Thread.sleep(100); (но в реальности избегайте блокировок!)
sub.request(1); // После каждого — запрашиваем следующий
}

@Override
public void onError(Throwable t) { /* обработка */ }
@Override
public void onComplete() { System.out.println("Готово"); }
});

Здесь подписчик контролирует темп: запросил 5 — получил 5, обработал — запросил ещё. Если не request() — поток остановится. Это асинхронно: издатель не блокируется, а ждёт сигналов.



#Java #middle #Reactor #Reactive_Streams_API #backpressure
👍2
Стратегии обработки backpressure: что если запросов мало?

Не всегда подписчик может обрабатывать всё. Reactive Streams не диктует, что делать при переполнении — это на усмотрение реализации (как Reactor).

Вот стратегии, чтобы не упасть:
- BUFFER (буферизация): Копирует лишние элементы в очередь (буфер). Полезно для временных пиков, но рискуете памятью при бесконечном потоке. В Reactor: .onBackpressureBuffer().
- DROP (сброс): Игнорирует лишние элементы, пока подписчик не запросит. Для сценариев, где свежие данные важнее старых (например, мониторинг). .onBackpressureDrop().
- LATEST (последний): Сохраняет только самый свежий элемент, сбрасывая предыдущие. Идеально для UI-обновлений (как курс валют). .onBackpressureLatest().
- ERROR (ошибка): Если буфер полон — кидает исключение (IllegalStateException). Для строгих систем, где потеря данных недопустима. .onBackpressureError().


Пример с DROP в Reactor:

Flux.interval(Duration.ofMillis(1)) // Бесконечный поток: элемент каждую мс
.onBackpressureDrop(dropped -> System.out.println("Сброшено: " + dropped)) // Стратегия: сбрасываем лишнее
.subscribe(item -> {
try { Thread.sleep(100); } catch (InterruptedException e) {} // Медленный подписчик
System.out.println("Обработано: " + item);
});

Здесь быстрый Flux "замедляется" под подписчика: лишние элементы сбрасываются, система не падает.

Ещё опция — cancel(): подписчик может полностью отменить подписку, если данных слишком много или не нужно.



Практические советы и подводные камни

- Всегда вызывайте request() в onSubscribe, иначе ничего не потечёт. Для неограниченного — request(Long.MAX_VALUE), но только если уверены в памяти.
- Избегайте блокировок в onNext: если обработка медленная, offload на другой Scheduler (в Reactor: .publishOn(Schedulers.parallel())).
- Тестируйте под нагрузкой: используйте TestPublisher/TestSubscriber для симуляции быстрых/медленных сценариев.
- Камень: бесконечные потоки без стратегии — рецепт OOM. Всегда добавляйте .onBackpressureBuffer(размер) или drop.


В реальной жизни: в Spring WebFlux backpressure работает сквозь стек — от БД (reactive драйверы) до клиента. Например, стриминг больших файлов: клиент запрашивает chunks, сервер толкает по мере.

#Java #middle #Reactor #Reactive_Streams_API #backpressure
👍3
Есть идея, создать закрытый чат, для тех кто хочет неформального активного общения и обсуждений, с строгими правилами.

Вы бы присоединились?
Anonymous Poll
58%
Да, выглядит многообещающе 🙂
33%
Наверно, но чем он лучше нынешнего, мертвого чата? 🤷‍♀️
8%
Нет, мне это не интересно 👎
👍1
Что выведет код?

public class Task260925 {
public static void main(String[] args) {
String a = "hello";
String b = "he" + "llo";
String c = "he";
String d = "llo";
String e = c + d;
String f = (c + d).intern();

System.out.print((a == b) + " ");
System.out.print((a == e) + " ");
System.out.print((a == f) + " ");
System.out.print(a.equals(e));
}
}


#Tasks
👍2
Продолжаем выбирать темы для разбора и голосовать за рассмотрение предложенных! 🤓

Голосуем за тему к рассмотрению в эти выходные!

Выбираем новую тему!
(можете предложить что-то из того, что предлагали на прошлой и позапрошлых неделях и что проиграло в голосовании!)

Не стесняемся! ✌️
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1
Вопрос с собеседований

Чем отличается процесс от потока?🤓

Ответ:

Процесс
— это экземпляр программы со своей памятью и ресурсами.

Потоки живут внутри процесса и делят общую память.

Потоки легче и быстрее переключаются, но требуют аккуратной синхронизации, чтобы избежать состояния гонки и неконсистентности данных.


#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🗓 История IT-технологий сегодня — 27 сентября


ℹ️ Кто родился в этот день

Ларри Уолл (англ. Larry Wall; род. 1954) американский программист. Знаменит как создатель языка программирования Perl. Лингвист по образованию. Автор клиента Usenet и широкоиспользуемой программы patch. Он дважды побеждал в международном конкурсе запутанного кода на языке программирования Си (IOCCC) и был лауреатом первой награды Free Software Foundation за продвижение свободного программного обеспечения (Free Software Foundation Award for the Advancement of Free Software) в 1998 году.


🌐 Знаковые события

1905Альберт Эйнштейн опубликовал работу «Зависит ли инерция тела от содержащейся в нём энергии?», в которой предлагалось знаменитое E=mc².

1983Ричард Столлман объявил, что в рамках проекта GNU должна быть создана UNIX-совместимая операционная система.

2007с космодрома Канаверал с помощью ракеты-носителя Дельта-2 запущена американская АМС Dawn (Рассвет), предназначенная для исследования астероидов Веста и Церера.


#Biography #Birth_Date #Events #27Сентября
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2🔥1
С 20.09 по 26.09
Предыдущий пост(с 13.09 по 19.09)

Воскресный мотивационный пост:
Ты не старый. Ты опытный.

Выбранная голосованием тема:
не было

Запись встреч/видео:
Spring AI Настройка и запуск. Историчность и RAG

Обучающие статьи:

Реактивное программирование

Концепции реактивного программирования:
Push vs Pull — кто управляет данными
Reactive Streams API — Publisher и Subscriber
Backpressure — что делать, если данных слишком много

Java:

Принципы проектирования и хорошего кода:
DRY, KISS, YAGNI
Композиция vs Наследование

Полезные статьи и видео
:

Проектирование БД рекомендательной системы по подходу DB-first
Что нового в Maven 4?

Три друга выбрали разные пути в IT. Какой Результат?

Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
👍4
Введение в GraphQL


GraphQL — это язык запросов для приложения, который позволяет клиентам (например, мобильным приложениям или веб-сайтам) запрашивать ровно те данные, которые им нужны, без лишнего. Он был создан компанией Facebook в 2012 году и стал открытым стандартом в 2015. В отличие от традиционных подходов, где сервер диктует, какие данные отдавать, здесь клиент сам формирует запрос. Это делает систему гибкой и эффективной.


Почему GraphQL вместо привычных методов?

Представь, что у тебя есть интернет-магазин. В старом подходе, называемом REST (это аббревиатура от "Representational State Transfer", что значит "передача состояния представления" — способ организации API, где каждый запрос идёт по фиксированному адресу), ты бы создал отдельные точки входа: одну для списка товаров, другую для деталей пользователя, третью для отзывов. Клиент запрашивает всё сразу, даже если ему нужно только имя товара и цена — и получает кучу лишних данных. Это тратит трафик и замедляет приложение.

GraphQL решает это одной точкой входа (обычно /graphql). Клиент пишет запрос на языке, похожем на JSON, указывая, какие поля нужны. Сервер возвращает только их.

Плюсы:
Меньше запросов: Можно получить данные из нескольких источников за один раз.
Типизация: Всё строго описано в схеме (это как каркас данных, где указано, какие типы полей и как они связаны).
Версионирование не нужно: Клиенты сами выбирают, что запрашивать, без изменений в API.
Интроспекция: Клиент может "спросить" сервер о доступных данных.


В экосистеме Java GraphQL интегрируется легко, особенно с Spring Boot — это фреймворк для быстрой разработки приложений на Java, который упрощает настройку серверов. Есть библиотека graphql-java, но для Spring лучше использовать spring-graphql — она берёт на себя интеграцию.


Настройка проекта: Шаги для старта

Давай создадим простой проект. Предполагаем, у тебя есть Java 17+ и Maven (система сборки проектов). Если новичок, скачай Spring Initializr с сайта spring.io — это онлайн-генератор проектов.

Создай проект Spring Boot с зависимостями:
Spring Web (для HTTP-сервера).
Spring GraphQL (для поддержки GraphQL).
Spring Data JPA (если нужно база данных, для хранения данных).
H2 Database (встроенная база для тестов).


В файле pom.xml (это конфигурация Maven) добавь:
xml<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-graphql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>


Определи схему. Схема — это файл с описанием типов данных.

Создай файл schema.graphqls в resources/graphql:
graphqltype Query {
bookById(id: ID): Book
allBooks: [Book]
}

type Book {
id: ID
title: String
author: Author
}

type Author {
id: ID
name: String
books: [Book]
}
Здесь Query — это корневой тип для запросов. ID — уникальный идентификатор, String — текст. [Book] значит список книг. Это позволяет запрашивать книги с авторами, и сервер сам свяжет данные.


Создай модель данных. В Java это классы с аннотациями (метками для фреймворка).

Для книги:
javaimport jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;

@Entity
public class Book {
@Id
private Long id;
private String title;
@ManyToOne
private Author author;

// Геттеры и сеттеры (методы для чтения и записи полей)
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getTitle() { return title; }
public void setTitle(String title) { this.title = title; }
public Author getAuthor() { return author; }
public void setAuthor(Author author) { this.author = author; }
}



#Java #middle #on_request #GraphQL
🔥3👍1
Репозитории для доступа к данным. Spring Data упрощает это:
javaimport org.springframework.data.jpa.repository.JpaRepository;

public interface BookRepository extends JpaRepository<Book, Long> {
}
Это интерфейс, который автоматически генерирует методы вроде findById.



Резолверы: Где происходит магия

Резолверы — это методы, которые "разрешают" запросы, то есть вычисляют данные.

В Spring создай класс:
javaimport graphql.kickstart.tools.GraphQLQueryResolver;
import org.springframework.beans.factory.annotation.Autowired;

public class QueryResolver implements GraphQLQueryResolver {
@Autowired
private BookRepository bookRepository;

public Book bookById(Long id) {
return bookRepository.findById(id).orElse(null); // Возвращает книгу или null, если не найдена
}

public List<Book> allBooks() {
return bookRepository.findAll(); // Все книги
}
}
@Autowired — это инъекция зависимости, Spring сам подставит репозиторий. Для автора аналогично создай AuthorResolver для поля books.


Чтобы связать автора с книгами, добавь резолвер для типа Book:
javaimport graphql.kickstart.tools.GraphQLResolver;

public class BookResolver implements GraphQLResolver<Book> {
public Author author(Book book) {
return book.getAuthor(); // Просто возвращает автора из модели
}
}
Это позволяет в запросе GraphQL получить автора без дополнительных усилий.



Запуск и тестирование

В основном классе приложения (обычно с @SpringBootApplication) ничего менять не нужно — Spring сам настроит /graphql.

Запусти приложение:
mvn spring-boot:run.


Теперь протестируй в инструменте вроде GraphiQL (встроен в Spring GraphQL, доступен по /graphiql).

Пример запроса:
graphqlquery {
bookById(id: 1) {
title
author {
name
}
}
}


Сервер вернёт:
json{
"data": {
"bookById": {
"title": "Война и мир",
"author": {
"name": "Лев Толстой"
}
}
}
}


Только то, что запрошено! Если нужно мутации (изменения данных), добавь type Mutation в схему и резолверы для createBook и т.д.


Продвинутые советы для опытных

Обработка ошибок: Используй GraphQLError для кастомных сообщений.
Производительность: Добавь DataLoader для batch-запросов, чтобы избежать N+1 проблемы (когда для списка из N элементов делается N запросов в базу).
Безопасность: Включи аутентификацию с Spring Security, ограничи поля по ролям.
Интеграция с другими сервисами: GraphQL может агрегировать данные из микросервисов.



Пример с DataLoader для оптимизации:

Сначала добавь зависимость graphql-java-tools.

Затем в конфигурации:
@Bean
public DataLoaderRegistry dataLoaderRegistry(BookRepository bookRepo) {
DataLoaderRegistry registry = new DataLoaderRegistry();
registry.register("authorLoader", DataLoader.newDataLoader((List<Long> authorIds) ->
CompletableFuture.supplyAsync(() -> bookRepo.findAuthorsByIds(authorIds)))); // Batch-запрос
return registry;
}


В резолвере используй контекст для загрузки.
Это делает систему масштабируемой.


#Java #middle #on_request #GraphQL
🔥3👍1