Главная страница
Навигация по странице:

  • 21. Расскажите про scope бинов. Какой scope используется по умолчанию Что изменилось в пятом Spring

  • 22. Что такое АОП Как реализовано в спринге

  • 23. Как спринг работает с транзакциями Расскажите про аннотацию @Transactional

  • 24. Расскажите про паттерн MVC, как он реализован в Spring

  • MVC (Model-View-Controller)

  • Модель (Model)

  • Контроллер (Controller)

  • ViewResolver

  • LocaleResolver

  • Ызкштп. Оглавление Введение 61. Что такое инверсия контроля (IoC) и внедрение зависимостей (DI) Как они реализованы в


    Скачать 1.17 Mb.
    НазваниеОглавление Введение 61. Что такое инверсия контроля (IoC) и внедрение зависимостей (DI) Как они реализованы в
    АнкорЫзкштп
    Дата01.11.2021
    Размер1.17 Mb.
    Формат файлаpdf
    Имя файлаmetodichka_06_Spring (3).pdf
    ТипДокументы
    #260853
    страница3 из 5
    1   2   3   4   5
    @PreDestroy
    Метод, аннотированный @PreDestroy, запускается только один раз, непосредственно перед тем, как Spring удаляет наш компонент из контекста приложения.
    Как и в случае с @PostConstruct, методы, аннотированные @PreDestroy, могут иметь любой уровень доступа, но не могут быть статическими.

    Целью этого метода может быть освобождение ресурсов или выполнение любых других задач очистки до уничтожения бина, например, закрытие соединения с базой данных.
    Обратите внимание, что аннотации @PostConstruct и @PreDestroy являются частью
    Java EE, а именно пакета javax.annotation модуля java.xml.ws.annotation. И поскольку Java EE
    устарела в Java 9
    , то с этой версии пакет считается устаревшим (Deprecated). С Java 11
    данный пакет вообще
    удален
    , поэтому мы должны добавить дополнительную зависимость
    для использования этих аннотаций:

    javax.annotation
    javax.annotation-api

    1.3
    .2



    21. Расскажите про scope бинов. Какой scope используется по умолчанию?
    Что изменилось в пятом Spring?
    Источники:
    Spring - Bean Scopes
    Mkyong - Spring 5 – Bean scopes
    YouTube - Alishev Урок 8: Жизненный цикл бина
    Spring Framework поддерживает шесть scopes:
    1. singleton
    2. prototype
    3. request
    4. session
    5. application
    6. websocket
    7. не активированный по умолчанию Custom thread scope.
    С 3 по 6 доступны только в веб-приложениях. Мы также можем создать свой собственный scope.
    Singleton
    Является дефолтным scope. В контейнере будет создан только один бин, и все запросы на него будут возвращать один и тот же бин. Этот бин хранится в контейнере, и все запросы и ссылки на этот бин возвращают закэшированный экземпляр.
    Prototype
    Scope “prototype” приводит к созданию нового бина каждый раз, когда он запрашивается.
    Для бинов со scope “prototype” Spring не вызывает метод destroy(). Spring не берет на себя контроль полного жизненного цикла бина со scope @prototype”. Spring не хранит такие бины в своём контексте ( контейнере), а отдаёт их клиенту и больше о них не заботится (в отличие от синглтон-бинов).
    Request
    Контейнер создает новый экземпляр для каждого HTTP-запроса. Таким образом, если сервер в настоящее время обрабатывает 50 запросов, тогда контейнер может иметь не более
    50 бинов, по одному для каждого HTTP-запроса. Любое изменение состояния одного экземпляра не будет видимо другим экземплярам. Эти экземпляры уничтожаются, как только
    HTTP-запрос завершен.
    @Component
    @Scope
    (
    "request"
    ) public class
    BeanClass
    {
    }
    //or
    @Component

    @RequestScope public class
    BeanClass
    {
    }
    Session
    Бин создается в одном экземпляре для одной HTTP-сессии. Таким образом, если сервер имеет 20 активных сессий, тогда контейнер может иметь не более 20 бинов, по одному для каждой сессии. Все HTTP-запросы в пределах времени жизни одной сессии будут иметь доступ к одному и тому же бину.
    @Component
    @Scope
    (
    "session"
    ) public class
    BeanClass
    {
    }
    //or
    @Component
    @SessionScope public class
    BeanClass
    {
    }
    Application
    Бин со scope “application” создается в одном экземпляре для жизненного цикла
    ServletContext. Виден как атрибут ServletContext. Синглтон - в одном экземпляре для
    ApplicationContext.
    @Component
    @Scope
    (
    "application"
    ) public class
    BeanClass
    {
    }
    //or
    @Component
    @ApplicationScope public class
    BeanClass
    {
    }
    Websocket
    Бин со scope “websocket” создается в одном экземпляре для определенного сеанса
    WebSocket. Один и тот же бин возвращается всякий раз, когда к нему обращаются в течение всего сеанса WebSocket.
    @Component
    @Scope
    (
    "websocket"
    ) public class
    BeanClass
    {
    }

    Custom thread scope
    Spring по умолчанию не предоставляет thread scope, но его можно активировать.
    Каждый запрос на бин в рамках одного потока будет возвращать один и тот же бин.
    В пятой версии Spring Framework не стало Global session scope.

    22. Что такое АОП? Как реализовано в спринге?
    Источники:
    Habr - Аспектно-ориентированное программирование, Spring AOP
    Введение в AOP в Spring Boot
    Shell26
    Аспектно-ориентированное
    программирование
    (АОП)
    — это парадигма программирования, целью которой является повышение модульности за счет разделения междисциплинарных задач. Это достигается путем добавления дополнительного поведения к существующему коду без изменения самого кода.
    АОП предоставляет возможность реализации в одном месте сквозной логики - т.е. логики, которая применяется к множеству частей приложения - и обеспечения автоматического применения этой логики по всему приложению.
    Подход Spring к АОП заключается в создании "динамических прокси" для целевых объектов и "привязывании" объектов к конфигурированному совету для выполнения сквозной логики.
    Прочитать статью

    23. Как спринг работает с транзакциями? Расскажите про аннотацию
    @Transactional
    Источники:
    Spring - Declarative transaction management
    Spring - Using @Transactional
    Spring API - @EnableTransactionManagement
    Spring API - @Transactional
    YouTube - Spring Framework - работаем с транзакциями
    Baeldung - Transactions with Spring and JPA
    Habr - Эффективное управление транзакциями в Spring
    Akorsa - Как на самом деле работает @Transactional Spring?
    Medium - Транзакции в Spring Framework
    Shell26 - Как управлять транзакциями в Spring
    Для работы с транзакциями Spring Framework использует AOP-прокси:
    Для включения возможности управления транзакциями первым делом нужно разместить аннотацию @EnableTransactionManagement у класса-конфигурации @Configuration.
    Аннотация @EnableTransactionManagement означает, что классы, помеченные
    @Transactional, должны быть обернуты аспектом транзакций. Однако, если мы используем
    Spring Boot и имеем зависимости spring-data-* или spring-tx, то управление транзакциями будет включено по умолчанию.
    @EnableTransactionManagement отвечает за регистрацию необходимых компонентов
    Spring, таких как TransactionInterceptor и советы прокси (proxy advices- набор инструкций, выполняемых на точках среза - Pointcut). Регистрируемые компоненты помещают перехватчик в стек вызовов при вызове методов @Transactional.
    Spring создает прокси для всех классов, помеченных @Transactional (либо если любой из методов класса помечен этой аннотацией). Прокси-объекты позволяют Spring Framework
    вводить транзакционную логику до и после вызываемого метода - главным образом для запуска и коммита/отката транзакции.
    Если мы разместим аннотацию @Transactional над классом @Service, то все его методы станут транзакционными. Так, при вызове, например, метода save() произойдет примерно
    следующее:
    1. Вначале мы имеем:
    ❖ класс TransactionInterceptor, у которого основной метод invoke(...), внутри которого вызывается метод класса-родителя TransactionAspectSupport: invokeWithinTransaction(...)
    , в рамках которого происходит магия транзакций.
    ❖ TransactionManager: решает, создавать ли новый EntityManager и/или транзакцию.
    ❖ EntityManager proxy: EntityManager - это интерфейс, и то, что внедряется в бин в слое DAO на самом деле не является реализацией EntityManager. В это поле внедряется EntityManager proxy, который будет перехватывать обращение к полю EntityManager и делегировать выполнение конкретному EntityManager в рантайме.
    Обычно
    EntityManager proxy представлен классом
    SharedEntityManagerInvocationHandler.
    2. Transaction Interceptor
    В TransactionInterceptor отработает код до работы метода save(), в котором будет определено, выполнить ли метод save() в пределах уже существующей транзакции БД или должна стартовать новая отдельная транзакция. TransactionInterceptor сам не содержит логики по принятию решения, решение начать новую транзакцию, если это нужно, делегируется TransactionManager. Грубо говоря, на данном этапе наш метод будет обёрнут в try-catch и будет добавлена логика до его вызова и после: try
    { transaction.begin();
    // логика до service.save();
    // логика после transaction.commit();
    } catch
    (Exception ex) { transaction.rollback(); throw ex;
    }
    3. TransactionManager
    Менеджер транзакций должен предоставить ответ на два вопроса:
    ❖ Должен ли создаться новый EntityManager?
    ❖ Должна ли стартовать новая транзакция БД?
    TransactionManager принимает решение, основываясь на следующих фактах:
    ❖ выполняется ли хоть одна транзакция в текущий момент или нет;
    ❖ атрибута «propagation» у метода, аннотированного @Transactional (для примера, значение REQUIRES_NEW всегда стартует новую транзакцию).
    Если TransactionManager решил создать новую транзакцию, тогда:
    ❖ Создается новый EntityManager;

    ❖ EntityManager «привязывается» к текущему потоку (Thread);
    ❖ «Получается» соединение из пула соединений БД;
    ❖ Соединение «привязывается» к текущему потоку.
    И EntityManager и это соединение привязываются к текущему потоку, используя переменные ThreadLocal.
    4. EntityManager proxy
    Когда метод save() слоя Service делает вызов метода save() слоя DAO, внутри которого вызывается, например, entityManager.persist(), то не происходит вызов метода persist() напрямую у EntityManager, записанного в поле класса DAO. Вместо этого метод вызывает
    EntityManager proxy, который достает текущий EntityManager для нашего потока, и у него вызывается метод persist().
    5. Отрабатывает DAO-метод save().
    6. TransactionInterceptor
    Отработает код после работы метода save(), а именно будет принято решение по коммиту/откату транзакции.
    Кроме того, если мы в рамках одного метода сервиса обращаемся не только к методу save(), а к разным методам Service и DAO, то все они буду работать в рамках одной транзакции, которая оборачивает этот метод сервиса.
    Вся работа происходит через прокси-объекты разных классов. Представим, что у нас в классе сервиса только один метод с аннотацией @Transactional, а остальные нет. Если мы вызовем метод с @Transactional, из которого вызовем метод без @Transactional, то оба будут отработаны в рамках прокси и будут обернуты в нашу транзакционную логику. Однако, если мы вызовем метод без @Transactional, из которого вызовем метод с @Transactional, то они уже не будут работать в рамках прокси и не будут обернуты в нашу транзакционную логику.
    У @Transactional есть ряд параметров:
    ❖ @Transactional (isolation=Isolation.READ_COMMITTED) - уровень изоляции.
    ❖ @Transactional(timeout=60) - По умолчанию используется таймаут, установленный по умолчанию для базовой транзакционной системы. Сообщает TransactionManager-у о продолжительности времени, чтобы дождаться простоя транзакции, прежде чем принять решение об откате не отвечающих транзакций.
    ❖ @Transactional(propagation=Propagation.REQUIRED)
    -
    (Если не указано, распространяющееся поведение по умолчанию — REQUIRED.) Указывает, что целевой метод не может работать без другой транзакции. Если до вызова этого метода уже была запущена транзакция, то метод будет работать в той же транзакции, если транзакции не было, то будет создана новая.
    REQUIRES_NEW -Указывает, что новая транзакция должна запускаться каждый раз при вызове целевого метода. Если транзакция уже идет, она будет приостановлена, прежде чем будет запущена новая.

    MANDATORY - Указывает, что для целевого метода требуется активная транзакция. Если активной транзакции нет, метод не сработает и будет выброшено исключение.
    SUPPORTS - Указывает, что целевой метод может выполняться независимо от наличия транзакции. Если транзакция работает, он будет участвовать в той же транзакции. Если транзакции нет, он всё равно будет выполняться, если не будет ошибок. Методы, которые извлекают данные, являются лучшими кандидатами для этой опции.
    NOT_SUPPORTED - Указывает, что целевой метод не требует распространения контекста транзакции. В основном те методы, которые выполняются в транзакции, но выполняют операции с оперативной памятью, являются лучшими кандидатами для этой опции.
    NEVER - Указывает, что целевой метод вызовет исключение, если выполняется в транзакционном процессе. Этот вариант в большинстве случаев не используется в проектах.
    ❖ @Transactional
    (rollbackFor=Exception.class)
    -
    Значение по умолчанию: rollbackFor=RunTimeException.class В Spring все классы API бросают RuntimeException, это означает, что если какой-либо метод не выполняется, контейнер всегда откатывает текущую транзакцию. Проблема заключается только в проверяемых исключениях.
    Таким образом, этот параметр можно использовать для декларативного отката транзакции, если происходит Checked Exception.
    ❖ @Transactional (noRollbackFor=IllegalStateException.class) - Указывает, что откат не должен происходить, если целевой метод вызывает это исключение. Если внутри метода с @Transactional есть другой метод с аннотацией @Transactional (вложенная транзакция), то отработает только первая (в которую вложена), из-за особенностей создания proxy.

    24. Расскажите про паттерн MVC, как он реализован в Spring?
    Источники:
    Javastudy - Spring MVC – основные понятия, архитектура
    Medium - Introduction to Spring MVC (Part 1)
    Wiki - Model–view–controller
    Habr - Spring MVC — основные принципы
    Wiki - Spring MVC
    YouTube - Алишев Spring MVC. Конфигурация с помощью Java кода.
    Baeldung - Quick Guide to Spring Controllers
    Baeldung - Spring MVC Interview Questions
    Marcobehler - What is Spring MVC
    MVC (Model-View-Controller)
    Это шаблон проектирования программного обеспечения, который делит программную логику на три отдельных, но взаимосвязанных компонента: модель, представление и контроллер — таким образом, что модификация каждого компонента может осуществляться независимо.
    Модель (Model) предоставляет данные и реагирует на команды контроллера, изменяя своё состояние. Она содержит всю бизнес-логику приложения.
    Представление (View) отвечает за отображение пользователю данных из модели в нужном формате.
    Контроллер (Controller) содержит код, который отвечает за обработку действий пользователя и обменивается данными с моделью (любое действие пользователя в системе обрабатывается в контроллере).
    Основная цель следования принципам MVC — отделить реализацию бизнес-логики приложения (модели) от ее визуализации (вида). Такое разделение повысит возможность повторного использования кода.
    Польза применения MVC наиболее наглядна в случаях, когда пользователю нужно предоставлять одни и те же данные в разных формах. Например, в виде таблицы, графика или диаграммы (используя различные виды). При этом, не затрагивая реализацию видов, можно изменить реакции на действия пользователя (нажатие мышью на кнопке, ввод данных).
    Spring Web MVC
    Spring MVC - это оригинальный веб-фреймворк, основанный на Servlet API, предназначенный для создания веб-приложений на языке Java, с использованием двух самых популярных шаблонов проектирования - Front controller и MVC.
    Front controller (Единая точка входа) - паттерн, где центральный сервлет,
    DispatcherServlet, принимает все запросы и распределяет их между контроллерами, обрабатывающими разные URL.
    Spring MVC реализует четкое разделение задач, что позволяет нам легко разрабатывать и тестировать наши приложения. Данные задачи разбиты между разными компонентами:
    Dispatcher Servlet, Controllers, View Resolvers, Views, Models, ModelAndView, Model and Session
    Attributes, которые полностью независимы друг от друга, и отвечают только за одно направление. Поэтому MVC дает нам довольно большую гибкость. Он основан на интерфейсах
    (с предоставленными классами реализации), и мы можем настраивать каждую часть фреймворка с помощью пользовательских интерфейсов.

    Основные интерфейсы для обработки запросов:
    HandlerMapping. По запросу определяет, какие перехватчики (interceptors) с пре- и пост- процессорной обработкой запроса должны отработать, а затем решает, какому контроллеру
    (обработчику) нужно передать данный запрос на исполнение. Процесс их определения основан на некоторых критериях, детали которых зависят от реализации HandlerMapping.
    Двумя основными реализациями
    HandlerMapping являются
    RequestMappingHandlerMapping
    (который поддерживает аннотированные методы
    @RequestMapping) и SimpleUrlHandlerMapping (который поддерживает явную регистрацию путей URI для обработчиков).
    HandlerAdapter. Помогает DispatcherServlet вызвать обработчик, сопоставленный с запросом. Для вызова аннотированного контроллера необходимо прочитать аннотации над методами контроллера и принять решение. Основная цель HandlerAdapter - избавить
    DispatcherServlet от этой рутины.
    ViewResolver. Сопоставляет имена представлений, возвращаемых методами контроллеров, с фактическими представлениями (html-файлами).
    View. Отвечает за возвращение ответа клиенту в виде текстов и изображений.
    Используются встраиваемые шаблонизаторы (Thymeleaf, FreeMarker и т.д.), так как у Spring нет родных. Некоторые запросы могут идти прямо во View, не заходя в Model, другие проходят через все слои.
    LocaleResolver. Определение часового пояса и языка клиента для того, чтобы предложить представления на его языке.
    MultipartResolver. Обеспечивает Upload — загрузку на сервер локальных файлов клиента. По умолчанию этот интерфейс не включается в приложении и необходимо указывать его в файле конфигурации. После настройки любой запрос о загрузке будет отправляться этому интерфейсу.
    FlashMapManager. Сохраняет и извлекает «входной» и «выходной» FlashMap, который можно использовать для передачи атрибутов из одного запроса в другой, обычно через редирект.
    Ниже приведена последовательность событий, соответствующая входящему HTTP- запросу:
    ❖ После получения HTTP-запроса DispatcherServlet обращается к интерфейсу
    1   2   3   4   5


    написать администратору сайта