Java Portal | Программирование
13K subscribers
1.2K photos
98 videos
37 files
1.12K links
Присоединяйтесь к нашему каналу и погрузитесь в мир для Java-разработчика

Связь: @devmangx

РКН: https://clck.ru/3H4WUg
Download Telegram
Spring Boot: чтобы прогнать SQL-скрипты до или после выполнения тестового метода, можно использовать аннотацию @Sql.

@SpringBootTest
@Sql("/test/products.sql")
class ProductServiceTest {

@Autowired
ProductService productService;

@Test
void findProductByName() {
Product product = productService.findByName("product1");
assertThat(product).isNotNull();
}
}


👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5
Что такое Throwable

Throwable в Java — это базовый класс для всех «бросаемых» аномалий. Он даёт общий функционал для работы с исключениями: стек, причину, вложенные ошибки и т. д.

С точки зрения модели: невосстанавливаемые критические состояния представлены через Error, а ошибки уровня приложения — через Exception.

То есть всё, что можно бросать (throw), наследуется от Throwable.

Коротко:

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

checked: обработка контролируется компилятором
unchecked: обработка не принудительная

Иерархия выглядит примерно так:

java.lang.Object
└─ java.lang.Throwable // всё, что можно throw-нуть
├─ java.lang.Error // системные критические сбои
│ ├─ OutOfMemoryError
│ ├─ StackOverflowError
│ ├─ VirtualMachineError
│ └─ ...
└─ java.lang.Exception // исключения уровня приложения
├─ RuntimeException // unchecked
│ ├─ NullPointerException
│ ├─ IllegalArgumentException
│ ├─ IndexOutOfBoundsException
│ └─ ...
└─ IOException, SQLException (checked)


Разница между Error и Exception


Error — «фатальный и невосстанавливаемый сбой»
Exception — «аномалия, которую приложение может ожидать и обрабатывать»

Мини сравнение:

источник: Error приходит от JVM и рантайма, Exception рождается на уровне приложения
восстановление: у Error почти нулевые шансы, у Exception всё зависит от ситуации
catch: Error обычно не ловят, Exception ловят и обрабатывают
примеры: для Error — OOM, StackOverflow; для Exception — неверный ввод или I/O ошибки

Что такое Error

Это фатальные сбои JVM.
Не то, что будут фиксить в бизнес-логике.

Примеры: OutOfMemoryError, StackOverflowError, VirtualMachineError

Почему их не ловят?

предпосылки работы программы уже нарушены
даже если поймать — непонятно, что делать дальше
нормальная стратегия — дать процессу упасть

Что такое Exception

Это исключения, которые приложение может предусматривать и включать в контрольный поток.

checked: IOException, SQLException
unchecked: NullPointerException, IllegalArgumentException

Почему их обрабатывают?
Потому что они «возможны по контракту» — неверный ввод, I/O, бизнес-валидация и т. д.

Почему в GlobalExceptionHandler не ловят Throwable

Потому что обработка Throwable приводила бы к поглощению Error (фатальных ошибок), и приложение продолжило бы работать в «сломанных» условиях.

Подробности:

➡️Поглощение Error
Если OutOfMemoryError превратить в обычный 500, то это попытка «делать вид, что всё ок», в то время как приложение фактически в предсмертном состоянии.

➡️Ломается контрольный поток фреймворка
Например, в Spring разное поведение завязано на тип исключения. Throwable ломает эти правила.

➡️Падает наблюдаемость
«Ловить всё» засоряет логи шумом и усложняет поиск корня проблемы.

Отсюда правило: в GlobalExceptionHandler ловят не Throwable, а Exception (или RuntimeException) как конечный уровень обработки в приложении.

👉 Java Portal
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
Spring Boot: можно переопределять конфиги на рантайме без перепаковки приложения.

Spring Boot по умолчанию использует лаунчер JarLauncher, который позволяет переопределить дефолтную конфигурацию через параметр loader.path при запуске приложения.

Предположим, у вас есть Spring Boot приложение со следующими зависимостями:

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>


С application.properties такого вида:

demo.message=Hello from inside the JAR


И простой контроллер:

@RestController
public class HelloController {

@Value("${demo.message}")
private String message;

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


Если собрать jar и запустить:

java -jar springboot-propertieslauncher-demo-0.0.1-SNAPSHOT.jar


Открыв [https://localhost:8080](https://localhost:8080) вы получите:

Hello from inside the JAR


Если теперь создать внешний файл application.properties в той же директории, где лежит jar:

demo.message=Hello from outside the JAR


И запустить приложение с параметром loader.path, указывающим на текущую директорию:

java -jar springboot-propertieslauncher-demo-0.0.1-SNAPSHOT.jar --loader.path=.


Перейдя в [https://localhost:8080](https://localhost:8080) будет:

Hello from outside the JAR


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