Spring Boot: если в коде используется RestTemplate, тесты можно писать, подменяя внешние HTTP-вызовы с помощью MockRestServiceServer.
✅ MockRestServiceServer работает за счет перехвата HTTP-запросов.
Дан сервис, который дергает внешний API:
Тест можно реализовать так:
👉 Java Portal
Дан сервис, который дергает внешний API:
@Service
public class ProductService {
private final RestTemplate restTemplate;
public ProductService(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public String getProductName(long id) {
Product product = restTemplate.getForObject(
"https://remoteapi.com/products/{id}",
Product.class,
id
);
return product.getName();
}
}
Тест можно реализовать так:
@SpringBootTest
class ProductServiceTest {
@Autowired
private RestTemplate restTemplate;
@Autowired
private ProductService productService;
private MockRestServiceServer mockServer;
@BeforeEach
void setup() {
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
void shouldReturnProductWhenExternalApiCalled() {
// Arrange
mockServer.expect(requestTo("https://remoteapi.com/products/1"))
.andExpect(method(HttpMethod.GET))
.andRespond(withSuccess(
"{\"id\":1,\"name\":\"USB stick\"}",
MediaType.APPLICATION_JSON
));
// Act
ProductDto product = productService.getProduct(1L);
// Assert
assertThat(product.getName()).isEqualTo("USB stick");
mockServer.verify();
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤4🔥2😁2
Нашли офигенный способ выучить PostgreSQL в браузере : crunchydata
PostgreSQL-песочница с практическими уроками SQL, транзакциям, индексам, PostGIS и не только
🛌
👉 Java Portal
PostgreSQL-песочница с практическими уроками SQL, транзакциям, индексам, PostGIS и не только
Please open Telegram to view this post
VIEW IN TELEGRAM
👍12❤2😁1
Java: не пихай бизнес-логику в Stream.peek(). Используй его только для отладки.
Смысл простой: peek() предназначен для легкого дебага и просмотра потока, а не для вычислений или побочных эффектов.
Используй только для легкой отладки
Пример: просмотр (инспекция) потока пайплайна
👉 Java Portal
Смысл простой: peek() предназначен для легкого дебага и просмотра потока, а не для вычислений или побочных эффектов.
Используй только для легкой отладки
Пример: просмотр (инспекция) потока пайплайна
list.stream()
.filter(x -> x > 10)
.peek(x -> System.out.println("Filter: " + x))
.map(x -> x * 2)
.peek(x -> System.out.println("Map: " + x))
.toList();
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤4
Выбирай направление:
Промпты, обучение, шпаргалки и полезные ресурсы на каждую тему!
Please open Telegram to view this post
VIEW IN TELEGRAM
🌚2🔥1
Под капотом многопоточной синхронизации в Java: как потоки договариваются через Mark Word
Синхронизация в Java часто воспринимается как простая языковая конструкция — достаточно использовать ключевое слово synchronized, и код начинает «просто работать».
На практике же на уровне JVM происходит цепочка событий, которую можно проследить до Mark Word — восьмибайтового служебного поля заголовка каждого Java-объекта.
Современные JVM (HotSpot, OpenJ9, GraalVM) не используют фиксированную модель блокировок. Вместо этого они динамически выбирают стратегию синхронизации, исходя из реального поведения потоков и истории использования объекта.
Эта статья предназначена для Java‑разработчиков, которые уже знакомы с многопоточностью и synchronized, но хотят разобраться, как именно JVM управляет блокировками, какие состояния проходит объект и какую роль в этом играет Mark Word.
👉 Java Portal
Синхронизация в Java часто воспринимается как простая языковая конструкция — достаточно использовать ключевое слово synchronized, и код начинает «просто работать».
На практике же на уровне JVM происходит цепочка событий, которую можно проследить до Mark Word — восьмибайтового служебного поля заголовка каждого Java-объекта.
Современные JVM (HotSpot, OpenJ9, GraalVM) не используют фиксированную модель блокировок. Вместо этого они динамически выбирают стратегию синхронизации, исходя из реального поведения потоков и истории использования объекта.
Эта статья предназначена для Java‑разработчиков, которые уже знакомы с многопоточностью и synchronized, но хотят разобраться, как именно JVM управляет блокировками, какие состояния проходит объект и какую роль в этом играет Mark Word.
Please open Telegram to view this post
VIEW IN TELEGRAM
Хабр
Под капотом многопоточной синхронизации в Java: как потоки договариваются через Mark Word
Синхронизация в Java часто воспринимается как простая языковая конструкция — достаточно использовать ключевое слово synchronized , и код начинает «просто работать». На практике же на уровне JVM...
🔥3
Java подсказка : не злоупотребляй наследованием. Когда можно — лучше делегируй. Наследование создаёт сильную связку, и это может выстрелить в ногу, если базовый класс изменится.
Предположим, у нас есть такой класс:
и Car наследуется от Engine:
Наследование выражает отношение is, но автомобиль на самом деле не является двигателем, он имеет двигатель. Перепишем через делегацию:
Таким образом эти два класса развязаны, и отношение превращается в has.
👉 Java Portal
Предположим, у нас есть такой класс:
class Engine {
void start() {
}
}и Car наследуется от Engine:
class Car extends Engine {
void drive() {
start();
}
}Наследование выражает отношение is, но автомобиль на самом деле не является двигателем, он имеет двигатель. Перепишем через делегацию:
class Car {
private Engine engine;
Car(Engine engine) {
this.engine = engine;
}
void drive() {
engine.start();
}
}Таким образом эти два класса развязаны, и отношение превращается в has.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8❤1
А может ли Java гонять TensorFlow без JNI и без Python?
Автор взял Java 25 + FFM и протащил это всё до C-шного TensorFlow API, собрав рабочий REST-сервис на macOS.
Результат: предсказуемая память, нативная производительность и максимально скучная (в хорошем смысле) архитектура.
Ломали когда-нибудь Quarkus-эндпоинт просто тем, что решили залогировать request body?
В этом гайде показывают, как безопасно аудировать, чистить и трассировать HTTP-запросы через request filters в Quarkus, не блокируя обработку и не убивая API.
Практично и можно почти копипастить.
👉 Java Portal
Автор взял Java 25 + FFM и протащил это всё до C-шного TensorFlow API, собрав рабочий REST-сервис на macOS.
Результат: предсказуемая память, нативная производительность и максимально скучная (в хорошем смысле) архитектура.
Ломали когда-нибудь Quarkus-эндпоинт просто тем, что решили залогировать request body?
В этом гайде показывают, как безопасно аудировать, чистить и трассировать HTTP-запросы через request filters в Quarkus, не блокируя обработку и не убивая API.
Практично и можно почти копипастить.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤3👀3
Java: не вешай логику в Stream.peek(), используй его только для отладки.
Используй его для легкой отладки
Пример: инспекция потока пайплайна
👉 Java Portal
Используй его для легкой отладки
Пример: инспекция потока пайплайна
list.stream()
.filter(x -> x > 10)
.peek(x -> System.out.println("Filter: " + x))
.map(x -> x * 2)
.peek(x -> System.out.println("Map: " + x))
.toList();
Please open Telegram to view this post
VIEW IN TELEGRAM
🤔3
Spring Boot. Чтобы Jackson создавал объекты из JSON явно и предсказуемо, можно использовать аннотацию
Каждый параметр явно биндится.
Определяем конструктор с
👉 Java Portal
@JsonCreatorКаждый параметр явно биндится.
Определяем конструктор с
@JsonCreator:class User {
public final String username;
public final int age;
@JsonCreator
public User(
@JsonProperty("username") String username,
@JsonProperty("age") int age
) {
this.username = username;
this.age = age;
}
}Please open Telegram to view this post
VIEW IN TELEGRAM
❤11
Многопоточность позволяет писать так, чтобы несколько задач выполнялись параллельно внутри одного приложения.
Чтобы использовать многопоточность (то есть писать многопоточный код), нужен класс java.lang.Thread.
Стадии жизненного цикла потока:
• New: Новый поток начинает жизнь в состоянии new. Он остается там, пока программа не запустит поток.
• Runnable: После запуска новый поток становится runnable. В этом состоянии считается, что поток выполняет свою работу.
• Waiting: Иногда поток переходит в waiting, когда ему нужно дождаться выполнения задачи другим потоком.
• Timed Waiting: Поток из runnable может перейти в timed waiting на определенный промежуток времени. После истечения этого времени он снова возвращается в runnable.
• Terminated: Поток попадает в terminated после завершения задачи или принудительного завершения.
Приоритеты потоков:
Каждый Java-поток имеет приоритет, который помогает ОС решать порядок планирования потоков.
• MIN_PRIORITY (константа 1)
• NORM_PRIORITY (константа 5) (приоритет по умолчанию)
• MAX_PRIORITY (константа 10)
Базовые способы создать поток в Java:
• Реализовать интерфейс Runnable
• Наследоваться от Thread
Методы потоков:
• public void start()
Запускает поток в отдельном пути выполнения и затем вызывает run() у этого объекта Thread.
• public void run()
Если объект Thread был создан с отдельным Runnable, то run() будет вызван на этом Runnable.
• public final void setPriority(int priority)
Устанавливает приоритет потока. Возможные значения от 1 до 10.
• public void interrupt()
Прерывает поток, заставляя продолжить выполнение, даже если он был заблокирован.
• public final boolean isAlive()
Возвращает true, если поток "жив", то есть после старта и до завершения.
Это были базовые вещи. Пост длинный, но надеюсь, что что-то новое унес с собой.
👉 Java Portal
Чтобы использовать многопоточность (то есть писать многопоточный код), нужен класс java.lang.Thread.
Стадии жизненного цикла потока:
• New: Новый поток начинает жизнь в состоянии new. Он остается там, пока программа не запустит поток.
• Runnable: После запуска новый поток становится runnable. В этом состоянии считается, что поток выполняет свою работу.
• Waiting: Иногда поток переходит в waiting, когда ему нужно дождаться выполнения задачи другим потоком.
• Timed Waiting: Поток из runnable может перейти в timed waiting на определенный промежуток времени. После истечения этого времени он снова возвращается в runnable.
• Terminated: Поток попадает в terminated после завершения задачи или принудительного завершения.
Приоритеты потоков:
Каждый Java-поток имеет приоритет, который помогает ОС решать порядок планирования потоков.
• MIN_PRIORITY (константа 1)
• NORM_PRIORITY (константа 5) (приоритет по умолчанию)
• MAX_PRIORITY (константа 10)
Базовые способы создать поток в Java:
• Реализовать интерфейс Runnable
• Наследоваться от Thread
Методы потоков:
• public void start()
Запускает поток в отдельном пути выполнения и затем вызывает run() у этого объекта Thread.
• public void run()
Если объект Thread был создан с отдельным Runnable, то run() будет вызван на этом Runnable.
• public final void setPriority(int priority)
Устанавливает приоритет потока. Возможные значения от 1 до 10.
• public void interrupt()
Прерывает поток, заставляя продолжить выполнение, даже если он был заблокирован.
• public final boolean isAlive()
Возвращает true, если поток "жив", то есть после старта и до завершения.
Это были базовые вещи. Пост длинный, но надеюсь, что что-то новое унес с собой.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2
Spring Boot. С помощью
👉 Java Portal
@DataJpaTest можно прогонять JPA репозитории изолированно.@DataJpaTest поднимает только JPA слой без всего приложения, использует in-memory базу H2 и откатывает транзакции после каждого теста.Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍1
Поток обработки запроса в Spring Boot
Вопрос на собеседовании: как проходит HTTP-запрос внутри Spring Boot приложения?
Звучит просто, но на практике сложно правильно восстановить порядок и технические детали.
• клиент отправляет HTTP-запрос
• запрос сначала попадает в DispatcherServlet (Front Controller)
• DispatcherServlet через HandlerMapping ищет нужный контроллер
• контроллер занимается маппингом запроса и валидацией
• бизнес-логика выполняется в сервисном слое
• работа с базой идет через репозиторий (JPA)
• ответ идет обратно по тому же пути и сериализуется в JSON через Jackson
👉 Java Portal
Вопрос на собеседовании: как проходит HTTP-запрос внутри Spring Boot приложения?
Звучит просто, но на практике сложно правильно восстановить порядок и технические детали.
• клиент отправляет HTTP-запрос
• запрос сначала попадает в DispatcherServlet (Front Controller)
• DispatcherServlet через HandlerMapping ищет нужный контроллер
• контроллер занимается маппингом запроса и валидацией
• бизнес-логика выполняется в сервисном слое
• работа с базой идет через репозиторий (JPA)
• ответ идет обратно по тому же пути и сериализуется в JSON через Jackson
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7👍1
Spring Boot: чтобы прогнать SQL-скрипты до или после выполнения тестового метода, можно использовать аннотацию
👉 Java Portal
@Sql.@SpringBootTest
@Sql("/test/products.sql")
class ProductServiceTest {
@Autowired
ProductService productService;
@Test
void findProductByName() {
Product product = productService.findByName("product1");
assertThat(product).isNotNull();
}
}
Please open Telegram to view this post
VIEW IN TELEGRAM
👍2