Java Portal | Программирование
12.3K subscribers
1.35K photos
108 videos
42 files
1.35K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Совет по Java: начиная с Java 15 можно использовать String.formatted(...) для форматирования строк вместо String.format(...).

Работает как String.format, но выглядит немного чище и понятнее:

Вместо:

String message = String.format("Hello %s, you have %d messages", user, count);

System.out.println(String.format("Hello %s, you have %d messages", user, count));


Можно написать:

String message = "Hello %s, you have %d messages".formatted(user, count);

System.out.println("Hello %s, you have %d messages".formatted(user, count));


Также хорошо работает с многострочным форматированием:

String json = """
{
"user": "%s",
"messages": %d
}
""".formatted(user, count);


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍5🔥4
Java Spring Boot: Не допускайте эту ошибку с фильтрами/интерцепторами

Многие используют фильтры и интерцепторы неправильно

Они должны использоваться только для сквозных задач
(то есть для того, что применяется ко ВСЕМ запросам)

Примеры корректного использования:

[Фильтры]:

- CORS
- Кодировка

[Интерцепторы]:

- Аутентификация/Авторизация
- Метрики/Логирование
- Локаль
- Общие заголовки

[Основная ошибка]:

размещать там бизнес-логику

Например:

- выполнение запросов к базе данных
- проверка подписок
- сложная логика

Почему это плохо:

- выполняется для КАЖДОГО запроса
- создаёт дополнительную нагрузку
- нарушает архитектуру
- усложняет тестирование

Вывод:

- интерцептор превращается в «мусорный слой»

Как делать правильно:

- бизнес-логика → в сервисах
- контроллеры → оркестрация

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3👍1
Совет по Java : Если нужно посчитать количество вхождений элемента в списке, можно использовать Collections.frequency(...).

#Java #Collections

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍123
Большинство проектов на Spring Boot обрабатывают конфигурацию одинаково: плоские классы с @ConfigurationProperties, строковые имена свойств и надежда на то, что все прочитают README.

В Apereo CAS — более 1000 свойств в 633 конфигурационных классах. Автор написал статью о том, как система конфигурации остаётся навигируемой при таком масштабе:

https://medium.com/all-things-software/spring-boot-configuration-properties-at-scale-884f494721ac

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
3
Java 21 открывает новую эпоху конкурентности с виртуальными потоками — лёгкими потоками, управляемыми JVM, которые значительно повышают производительность I/O-bound приложений.

Подробнее - https://lttr.ai/Ap1Np

#Java #MongoDB #VirtualThread

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
2
Один JEP, к которому стоит вернуться: JEP 485 в JDK 24. Он вводит gather(...) для стримов — новую промежуточную операцию для преобразований, которые не укладываются в map, filter или flatMap. Небольшой пример 👇
1
Spring Boot: можно валидировать конфигурационные классы с помощью аннотации @Validated.

Это позволяет приложению падать на старте (fail fast), если конфигурация некорректна.

@Validated
@ConfigurationProperties(prefix = "app")
public class AppProperties {

@NotBlank
private String name;

@Min(1)
@Max(60)
private int timeout;

// getters/setters
}


#SpringBoot #JavaDev

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍93
#Java Совет: вы можете откатить транзакцию БД, созданную аннотацией @Transactional, получив текущий TransactionStatus через класс TransactionAspectSupport и установив для него rollback через setRollbackOnly();. Таким образом, не нужно выбрасывать исключение.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍102🔥1🤣1
Spring Boot: лучше избегать логирования внутри плотных циклов, так как это может повлиять на производительность приложения и привести к засорению лог-файлов.

Пример:

for (Order order : orders) {
log.info("Order {}", order.getId());
process(order);
}


Если orders большой, это может замедлить обработку и засорить лог-файлы.

Если логировать всё же нужно, лучше использовать уровень debug:

log.debug("Order: {}", order.getId());


Также можно добавить проверку, если требуется выполнить нетривиальные вычисления:

if (log.isDebugEnabled()) {
log.debug("Order: {}", expensiveElaboration());
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍54
Java API Tip

Безопасное приведение long к int

Используй Math.toIntExact() — этот метод возвращает значение long, но выбрасывает ArithmeticException, если оно не помещается в int

Без него преобразование произойдёт молча — и ты можешь получить некорректный результат без всяких ошибок.

Используй toIntExact, когда важно контролировать переполнение

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
8
💡Spring Boot: для чистых REST-контроллеров используйте
@RestController вместо @Controller + @ResponseBody

@RestController — это мета-аннотация, которая включает @ResponseBody, и затем автоматически применяется ко всем методам:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
}


С использованием @Controller и @ResponseBody:

@Controller
public class MyController {

@ResponseBody
@GetMapping("/hello")
public String hello() {
return "Hello!";
}
}


С использованием @RestController:

@RestController
public class MyController {

@GetMapping("/hello")
public String hello() {
return "Hello!";
}
}


#SpringBoot #CleanCode

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
7
В SpringFramework 7.1 появится поддержка @MockitoBean и @MockitoSpyBean на параметрах конструктора теста

Это работает с конструкторами в Java, но ещё удобнее с компактными конструкторами в Kotlin. Также это работает с так называемыми «test records» в Java. 🤓

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥1🤔1
Spring Boot: Лучше использовать SpringBootTest.WebEnvironment.RANDOM_PORT вместо жёстко заданных портов в тестах, чтобы избежать конфликтов.

#SpringBoot #JavaDev

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
6👍3
Прогрессивный практический туториал по изучению Agent Client Protocol (ACP) с использованием Java SDK: https://github.com/markpollack/acp-java-tutorial

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
5
По умолчанию Spring Boot не включает stacktrace в ответах REST-сервисов. Только для целей быстрого дебага (не используйте это в production) можно включить это через конфигурационное свойство include-stacktrace: always.
#SpringBoot #JavaDev

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
4
🔴 Завтра тестовое собеседование с Java-разработчиком

15 апреля(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.

Как это будет:
📂 Виктор Анохин, старший разработчик из WildBerries, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Виктор будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Виктору

Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.

Переходи в нашего бота, чтобы получить ссылку на эфир →
@shortcut_sh_bot

Реклама.
О рекламодателе.
Please open Telegram to view this post
VIEW IN TELEGRAM
1
This media is not supported in your browser
VIEW IN TELEGRAM
Освой Java с нуля

Этот бесплатный курс охватывает широкий спектр тем, начиная от базовых концепций, таких как переменные, массивы, условные операторы и циклы, до более сложных аспектов, включая ООП, работу с файлами, двумерные массивы и работу с базами данных.

Материалы включают теоретические объяснения, практические примеры кода, и иногда задачи для самостоятельного выполнения

Ссылка: тык

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
Spring Boot: есть возможность использовать стриминг (Stream<T>) для запросов с большими наборами данных.

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

В следующем примере есть приложение с CommandLineRunner, которое сохраняет большой набор пользователей в базу данных, а затем обрабатывает данные через стрим:

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

@Bean
CommandLineRunner run(UserRepository repo, UserService service) {
return args -> {
// Генерация тестовых данных
for (int i = 1; i <= 10000; i++) {
repo.save(new User("User_" + i));
}

// Обработка через стрим
service.processUsers();
};
}
}


Метод processUsers работает в транзакции и использует метод репозитория streamAllUsers, который возвращает стрим:

@Service
public class UserService {

private final UserRepository repository;

@PersistenceContext
private EntityManager em;

public UserService(UserRepository repository) {
this.repository = repository;
}

@Transactional(readOnly = true)
public void processUsers() {
AtomicInteger counter = new AtomicInteger();

try (Stream<User> stream = repository.streamAllUsers()) {
stream.forEach(user -> {
System.out.println(user.getName());

if (counter.incrementAndGet() % 100 == 0) {
em.clear();
}
});
}
}
}


public interface UserRepository extends JpaRepository<User, Long> {

@Query("SELECT u FROM User u")
Stream<User> streamAllUsers();
}


Важные моменты:

- Нужно использовать транзакцию, иначе соединение может закрыться раньше времени и стрим оборвётся
- Рекомендуется задать размер выборки через spring.jpa.properties.hibernate.jdbc.fetch_size=100, так как некоторые драйверы могут загрузить всё сразу
- Стрим удерживает ресурсы базы данных, его обязательно нужно закрывать (через try-блок, как в примере)

#SpringBoot #JavaDev

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
7👍2
Java: используйте WeakHashMap для кэширования, когда ключи без ссылок должны удаляться сборщиком мусора.

В HashMap, пока существует сама мапа, ключи и связанные с ними значения не будут удаляться сборщиком мусора.

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

Пример:

Map<User, String> map = new WeakHashMap<>();

User u1 = new User("Mick");
map.put(u1, "Cached data");
...
u1 = null;

// С этого момента ключ u1 доступен для сборки мусора.


#Java #JavaDev

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥73