Spring Flashcards
(37 cards)
@Transactional. Как работает?
@Transactional это аннотация, которой можно аннотировать класс или метод. Она позволяет автоматически управлять транзакциями.
Аннотацией @Transactional можно пометить класс, тогда все его методы станут транзакционными, или метод.
Дефолтный propagation установлен на значении Required.
Помимо управления транзакциями через @Transactional, ими можно также управлять и через TransactionManager и через TransactionTemplate (они обеспечивают полный контроль над транзакциями).
Если повесить @Transactional над приватным методом, то транзакция не будет создана, потому что Spring использует прокси механизм для управления транзакциями.
Атрибуты @Transactional: propagation, isolation, readOnly, timeout, rollbackFor, noRollbackFor
@Qualifier vs @Primary
Если есть два бина с одинаковым именем, то при внедрении одного из них вылезет exception. Чтобы решить эту проблему можно поставить над бином @Primary, тогда бин с этой аннотацией будет предпочтительнее для внедрения. Если же нам нужно 2 этих бина, то можно использовать @Qualifier и указать в нем имя для каждого бина.
Жизненный цикл бина
Создание бина -> Внедрение зависимостей -> Постобработка -> Инициализация -> Использование -> Уничтожение.
1) Предоставляем IoC контейнеру Bean Definitions при помощи BeanDefinitionReaders
2) Он их сортирует, чтобы сначала создавать те бины, у которых нет зависимостей, а потом уже бины, зависимые от других
3) Вызываем конструктор бина или фабричный метод
4) Внедряем свойства через поля, сеттеры, если нужно, то ставим имя бину и внедряем контекст в него
5) BeanPostProccesor метод postProcessBeforeInitialization()
6) Инициализация - @PostConstruct, метод init, afterPropertiesSet
7) BeanPostProccesor метод postProcessAfterInitialization()
На этом этапе мы уже получили готовый бин, если у него scope singleton, то
добавляем его в контекст и следим за ним, иначе просто возвращаем бин
8) Если бин был в контейнере, то для каждого бина вызывается еще
PreDestroy, destroy
Еще есть BeanFactoryPostProcessor, но они нужны для изменения BeanDefinition, например внедряют значения из пропертей
Dependency Injection
Это способ управления зависимостями, при котором мы не думаем об их инициализации.
Зачем мы используем Spring? Почему все так любят его?
Это фреймворк, который предоставляет множество возможностей для разработки приложений, является очень гибким и модульным.
Inversion of control
Это принцип, при котором мы передаем управление объектом спрингу.
Какие способы внедрения зависимостей знаешь?
Зависимости можно внедрять через конструктор, сеттер или поля.
Что такое Bean?
@Bean это аннотация, которая ставится над методом в конфигурационном классе, чтобы указать, что он вернет объект, который будет использоваться в Spring приложении. Метаданные о созданном бине хранятся в BeanDefinition (класс бина, скоуп, зависимости, методы инициализации и уничтожения). В бин нельзя передавать final или static поля.
@Service, @Repository, @Component
@Component – общая аннотация, которая ставится над классом, который
будет управляться Spring контейнером. Нужна для обычных бинов
@Service – по факту это тот же самый компонент, просто показывает
предназначение бина(что он принадлежит слою сервисов)
@Repository – тоже является компонентом, но еще приносит вместе с собой
логику обработки исключений(он их преобразует, например SQLException в
DataIntegrityViolationException). Показывает что бин работает с бд
@Controller – настройка маршрутизации, без него не будут приниматься запросы
Атрибут propagation у @Transactional
Этот атрибут отвечает за создание вложенных транзакций. У него есть следующие параметры:
REQUIRED - применяется по умолчанию, при входе в транзакцию будет использовано уже существующая или создана новая.
REQUIRES_NEW - для внутреннего метода создается своя отдельная транзакция. Пока выполняется внутренний метод, внешняя транзакция приостанавливается.
NESTED - создает транзакцию внутри основной транзакции.
MANDATORY - требует внешнюю транзакцию, а иначе выбрасывается исключение.
SUPPORTS - метод будет выполняться в рамках транзакции, если она существует, если ее нет метод выполнится без транзакции.
NOT_SUPPORTED - метод всегда выполняется вне транзакции, даже если существует текущая транзакция, то она приостанавливается.
NEVER - запрещает выполнение метода в транзакции.
Почему лучше использовать конструктор?
Лучше всего внедрять зависимости через конструктор, потому что это гарантирует невозможность изменения зависимостей и то что они 100% будут внедрены.
@Controller и @RestController
@Controller используется, чтобы возвращать веб-страницы, если нужно вернуть какие то данные, то нужно использовать аннотацию @ResponseBody.
@RestController это комбинация @ResponseBody и @Controller.
Spring Boot
Это фреймворк, который ускоряет разработку приложений. Ключевые преимущества:
Стартеры - это готовый набор библиотек, который включает в себя все необходимые зависимости.
Встроенный Tomcat сервер.
Автоматическая конфигурация.
Циклическая зависимость
Это когда два класса ссылаются друг на друга через аннотацию @Autowired, чтобы это решить нужно либо внедрить зависимости через сеттер, либо использовать аннотацию @Lazy.
@Conditional в Spring
Используется, если мы хотим включать бин, только если выполнены определенные условия.
@ConditionalOnBean - исполняется только если существует определенный бин.
@ConditionalOnProperty - исполняется, только если в конфигурационном файле есть определенное свойство.
Стартеры в Spring плюсы и минусы
Стартеры в SpringBoot - это преднастроенные зависимости и настройки, что позволяет быстро переходить к разработке приложений.
Минусы:
- Избыточная зависимость.
- Меньшая гибкость.
Плюсы:
- Упрощенная конфигурация.
- Согласованность.
- Сокращение времени разработки.
- Модульность.
Как обеспечить, чтобы при внедрении бина со скоупом prototype в singleton, каждый вызов получал новый экземпляр и какие проблемы могут возникнуть при этом, включая случаи с разными реализациями?
Существуют следующие способы:
- @Lookup
- ObjectProvider
- Прокси бин
- Получение из ApplicationContext
@ComponentScan
Указывает Spring, где искать классы помеченные аннотацией @Component (или ее псевдонимами).
Парадигма AOP
AOP – способ добавить нашему коду сквозную логику(логирование или обработка исключений), не внося изменения в саму функцию.
Состоит из 4 частей:
@Aspect – класс, который содержит сквозную логику
@Advice – совет, он выполняется до, после метода
@Join Point – точка соединения, место, где применяется наш аспект(вызов метода, исключение и т.д.)
@Pointcut – срез, выражение, которое определяет, к каким методам будет применяться аспект.
Это все реализовано с помощью прокси.
@Scheduled
Эта аннотация используется, чтобы запускать действия по определенному расписанию.
@PostConstruct
Указывает метод, который должен быть выполнен после инициализации бина. В бине можно задекларировать только один @PostConstruct метод.
SpringData JPA
Это модуль Spring, который упрощает работу с JPA. Он предоставляет удобные модули для работы с данными.
@Async
Аннотация @Async позволяет выполнять методы помеченные ей асинхронно (в отдельном потоке).
Принцип работы:
- Асинхронное выполнение (метод выполняется в отдельном потоке и возвращает void, Future или CompleteableFuture).
- Вызывается не сам метод, а его прокси.
- @Async использует пул потоков определенный в настройках (SimpleAsyncTaskExecutor по умолчанию).
Виды proxy в Spring
Spring использует динамическое proxy для создания AOP оберток над бинами.
Типы прокси:
- JDK Dynamic proxy (используется только для интерфейсов).
- CGLib proxy (используется для классов и создает подкласс оригинального класса).