Wiki for course "Java with Spring".
1. Spring Core
Spring Framework – это framework, который облегчает и ускоряет разработку приложений на Java.
Ключевым элементом Spring Framework является Spring Container, который выполняет основные функции:
-
IoC – Inversion of Control (Создание и управление объектами);
-
DI – Dependency Injection (внедрение зависимостей).
Container создаёт объекты, связывает их вместе, настраивает и управляет ими от создания до момента уничтожения. Эти объекты называются Spring Bean. Beans после создания помещаются в Spring Container.
В Spring имеется 2 различных вида контейнеров:
-
BeanFactory;
-
ApplicationContext.
BeanFactory Container самый простой контейнер, обеспечивающий базовую поддержку DI и который основан на интерфейсе org.springframework.beans.factory.BeanFactory
. Такие интерфейсы, как BeanFactoryAware
и DisposableBean
всё ещё присутствуют в Spring для обеспечения обратной совместимости. Наиболее часто используемая реализация интерфейса BeanFactory
– XmlBeanFactory
. XmlBeanFactory
получает метаданные из конфигурационного XML файла и использует его для создания настроенного приложения или системы.
BeanFactory Container обычно используется тогда, когда ресурсы ограничены (мобильные устройства). Поэтому, если ресурсы не сильно ограничены, то лучше использовать ApplicationContext.
Для того чтобы Spring Container мог создать и поместить в себя Beans необходимы:
-
Java классы (POJO), из которых создаются Beans
-
метаданные, которые подсказывают что и как создавать
Эти метаданные можно сконфигурировать несколькими способами:
-
Xml конфигурация;
-
Groovy конфигурация;
-
Конфигурация через аннотации;
-
Конфигурация через Java-код.
-
и т.д.
1.1. Bean и его атрибуты
Bean – это объект, экземпляр которого создается, собирается и иным образом управляется контейнером IoC Spring (создание, вызов методов инициализации и конфигурирование объектов путем связывания между собой).
Объекты, которые составляют основу приложения и управляются контейнером IoC Spring, называются Components (компонентами или управляемые Java-объект).
Определение Beans содержит метаданные конфигурации, которые необходимы управляющему контейнеру для получения следующей информации:
-
Как создать бин;
-
Информацию о жизненном цикле бина;
-
Зависимости бина.
С помощью этих метаданных (атрибуты бина) мы можем настраивать бины.
Bean имеет следующие атрибуты:
-
class - этот атрибут является обязательным и указывает конкретный класс Java-приложения, который будет использоваться для создания бина.
-
id/name- уникальный идентификатор бина. В случае конфигурации с помощью xml-файла, вы можете использовать свойство
id
и/илиname
для идентификации бина. -
scope - это свойство определяет область видимости создаваемых объектов.
-
constructor-arg - определяет конструктор, использующийся для внедрения зависимости. Имеет атрибут
ref
, который указывает наid
бина с которым нужно связываться. -
properties - определяет свойства внедрения зависимости.
-
initialization method - здесь определяется метод инициализации бина
-
destruction method - метод уничтожения бина, который будет использоваться при уничтожении контейнера, содержащего бин.
-
autowiring mode - определяет режим автоматического связывания при внедрении зависимости.
-
lazy-initialization mode - режим ленивой инициализации даёт контейнеру IoC команду создавать экземпляр бина при первом запросе, а не при запуске приложения.
1.2. Bean Scopes
Очень важной особенностью является задание области применения бинов. По умолчанию всегда используется singleton.
Scope (область видимости) определяет:
-
жизненный цикл бина;
-
возможное количество создаваемых бинов.
Разновидности bean scope:
-
Singleton – тип бина, при котором, создается одна сущность на Spring-контейнер (значение по умолчанию)
-
Prototype – тип бина, при котором, каждый раз создается новая сущность бина.
-
Request – тип бина, при котором сущность бина создается одна на request. Такой тип бина справедлив для контекста веб-приложения.
-
Session – тип бина, при котором сущность бина создается только одна на объект http-session. Такой тип бина справедлив для контекста веб-приложения.
-
Global-session – тип бина, при котором сущность бина одна создается на приложение. Такой тип бина справедлив для контекста портлета.
-
Application – тип бина, задаваемый в единственном экземпляре на контекст сервлета. Действителен для контекста веб-приложения.
1.3. Конфигурация
Как указывалось выше, существует 4 вида конфигурации метаданных для создания бинов:
-
Xml конфигурация —
ClassPathXmlApplicationContext("context.xml")
; -
Groovy конфигурация —
GenericGroovyApplicationContext("context.groovy")
; -
Конфигурация через аннотации с указанием пакета для сканирования —
AnnotationConfigApplicationContext("package.name")
; -
JavaConfig — конфигурация через аннотации с указанием класса (или массива классов) помеченного аннотацией
@Configuration
—AnnotationConfigApplicationContext(JavaConfig.class)
.
1.3.1. Xml конфигурация
Чтобы использовать настройку через xml-файл, необходимо создать ClassPathXmlApplicationContext
и в параметры передать CLASSPATH xml-файла.
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Ниже приведен пример простого конфигурационного файла xml applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean id = "villain" class = "film.Villain" lazy-init= "true">
<property name = "name" value = "Vasily"/>
</bean>
</beans>
1.3.2. Groovy конфигурация
При конфигурации контекста с помощью groovy-файла, необходимо сформировать GenericGroovyApplicationContext
, который принимает на вход строку с конфигурацией контекста. Эта конфигурация работает по сути так же, как и xml, только с groovy-файлами. К тому же, GroovyApplicationContext
нормально работает и с xml-файлом.
Пример простого конфигурационного Groovy-файла:
beans {
goodOperator(film.Operator) {bean - >
bean.lazyInit = 'true' >
name = 'Good Oleg'
}
badOperator(film.BadOperator){bean - >
bean.lazyInit = 'true' >
name = 'Bad Oleg' / >
}
}
1.3.3. Конфигурация через аннотации
При конфигурации через аннотации используются следующие аннотации:
-
@Component
-
@Repository
-
@Service
-
@Controller
-
@RestController
@Repository
public class CoolDaoImpl implements CoolDao {
@Override
public void doCRUD() {
//some logic here
}
}
@Service
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class CoolServiceImpl implements CoolService {
@Autowired
private CoolDao dao;
@PostConstruct
public void init() {
//init logic here
}
@PreDestroy
public void closeResources() {
//close resources here
}
@Override
public void doWork() {
dao.doCRUD();
}
}
1.3.4. Конфигурация через Java-код
Центральными артефактами при конфигурации через Java в Spring являются @Configuration
и @Bean
@Configuration
public class JavaConfig {
@Bean
public ClassName getClassName() {
return new ClassName();
}
@Bean(initMethod = "init", destroyMethod = "closeResources")
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public ClassName2 getClassName2() {
ClassName2 className = new ClassName2();
className.getClassName();
return service;
}
}
1.4. ApplicationContext
ApplicationContext
— это главный интерфейс в Spring-приложении, который предоставляет информацию о конфигурации приложения.
ApplicationContext
представляет собой Spring Container, место, где хранятся все созданные бины. Поэтому для получения бина из Spring Container нам нужно создать ApplicationContext
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
Чаще всего используются следующие реализации ApplicationContext
:
-
FileSystemXmlApplicationContext
- загружает данные о бине из xml-файла. При использовании этой реализации в конструкторе необходимо указать полный адрес конфигурационного файла. -
ClassPathXmlApplicationContext
- этот контейнер также получает данные о бине из xml-файла. Но в отличие отFileSystemApplicationContext
, в этом случае необходимо указать относительный адрес конфигурационного файла (CLASSPATH). -
WebXmlApplicationContext
- эта реализацияApplicationContext
получает необходимую информацию из веб-приложения. -
AnnotationConfigApplicationContext
- конфигурация через аннотации с указанием пакета для сканирования -
GenericGroovyApplicationContext
- конфигурация через groovy-файл
На рисунке ниже приведены этапы формирования ApplicationContext
:
1.4.1. Парсинг конфигурации и создание BeanDefinition
На первом этапе происходит чтение конфигураций и создание BeanDefinition
.
BeanDefinition
— это специальный интерфейс, через который можно получить доступ к метаданным будущего бина. В зависимости от того, какая у вас конфигурация, будет использоваться тот или иной механизм парсинга конфигурации.
XML config
Для xml конфигурации используется класс — XmlBeanDefinitionReader
, который реализует интерфейс BeanDefinitionReader
. XmlBeanDefinitionReader
получает InputStream
и загружает Document
через DefaultDocumentLoader
. Далее обрабатывается каждый элемент документа и если он является бином, то создается BeanDefinition
на основе заполненных данных (id
, name
, class
, alias
, init-method
, destroy-method
и др.)
Каждый BeanDefinition
помещается в map. Map хранится в классе DefaultListableBeanFactory
.
Groovy config
Конфигурация через groovy очень похожа на конфигурацию через xml, за исключением того, что в файл не xml, а groovy. Чтением и парсинг groovy конфигурации занимается класс GroovyBeanDefinitionReader
.
Annotations-based config
Для конфигурации через аннотации с указанием пакета для сканирования или JavaConfig используется класс AnnotationConfigApplicationContext
. Этот класс имеет следующие поля, с помощью которых происходит создание BeanDefinition
:
-
AnnotatedBeanDefinitionReader
; -
ClassPathBeanDefinitionScanner
.
ClassPathBeanDefinitionScanner
сканирует указанный пакет на наличие классов помеченных аннотацией @Component
(или любой другой аннотацией которая включает в себя @Component
). Найденные классы парсятся и для них создаются BeanDefinition
.
Чтобы сканирование было запущено, в конфигурации должен быть указан пакет для сканирования. Вся магия работы с аннотациями, как в случае с xml и groovy, заключается именно в классе ClassReader.class
из пакета springframework.asm
. Специфика этого ридера заключается в том, что он умеет работать с байт-кодом. То есть, ридер достает InputStream
из байт-кода, сканирует его и ищет там аннотации.
AnnotatedBeanDefinitionReader
работает в несколько этапов.
-
Первый этап: регистрация всех
@Configuration
для дальнейшего парсинга.
Если в конфигурации используются@Conditional
, то будут зарегистрированы только те конфигурации, для которых Condition вернетtrue
. Аннотация@Conditional
появилась в четвертой версии Spring Framework. Она используется в случае, когда на момент поднятия контекста нужно решить, создавать бин/конфигурацию или нет. Причем решение принимает специальный класс, который обязан реализовать интерфейсCondition
. -
Второй этап: регистрация специального
BeanFactoryPostProcessor
Если точнее, регистрацияBeanDefinitionRegistryPostProcessor
, который при помощи классаConfigurationClassParser
парсит JavaConfig и создаетBeanDefinition
.
Каждый BeanDefinition
помещается в map, который хранится в классе DefaultListableBeanFactory
.
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>();
1.4.2. Настройка созданных BeanDefinition
(BeanFactoryPostProcessor
)
После первого этапа у нас имеется map, в котором хранятся BeanDefinition
. На этом этапе у нас есть возможность повлиять на то, какими будут наши бины еще до их фактического создания, иначе говоря мы имеем доступ к метаданным класса. Для этого существует специальный интерфейс BeanFactoryPostProcessor
, реализовав который, мы получаем доступ к созданным BeanDefinition
и можем их изменять.
В этом интерфейсе всего один метод:
-
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
.
Метод postProcessBeanFactory()
принимает параметром ConfigurableListableBeanFactory
. Данная фабрика содержит много полезных методов, в том числе getBeanDefinitionNames()
, через который мы можем получить все BeanDefinitionNames
, а уже потом по конкретному имени получить BeanDefinition для дальнейшей обработки метаданных
1.4.3. Создание собственных FactoryBean
На этом этапе, если не устраивает BeanFactory из-под капота, можно создать собственные FactoryBean
.
FactoryBean
— это generic интерфейс, которому можно делегировать процесс создания бинов необходимого типа. В те времена, когда конфигурация была исключительно в xml, разработчикам был необходим механизм с помощью которого они бы могли управлять процессом создания бинов. Именно для этого и был сделан этот интерфейс.
Чтобы создать свою фабрику бинов (собственный FactoryBean
), необходимо реализовать интерфейс FactoryBean
и переопределить три его метода.
@Component
public class ClassNameFactory implements FactoryBean<ClassName> {
@Override
public ClassName getObject() throws Exception {
return new ClassName();
}
@Override
public Class<?> getObjectType() {
return ClassName.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
1.4.4. Создание экземпляров бинов
На этом этапе происходит создание бинов.
-
Созданием экземпляров бинов занимается BeanFactory при этом, если нужно, делегирует это кастомным FactoryBean.
-
Экземпляры бинов создаются на основе ранее созданных BeanDefinition.
-
При этом важно знать, что на этапе поднятия контекста создаются только бины с областью видимости Singleton.
-
Остальные бины создаются тогда, когда необходимы.
1.4.5. Настройка созданных бинов (BeanPostProcessor
)
На данном этапе можно производить дополнительную настройку созданных бинов. Настройка производиться через интерфейс BeanPostProcessor
.
BeanPostProcessor
- позволяет настраивать бины до того, как они попадут в Spring контейнер. Данный интерфейс имеет два метода.
-
postProcessBeforeInitialization(Object bean, String beanName)
; -
postProcessAfterInitialization(Object bean, String beanName)
.
BeanFactory
вызывает оба метода для каждого бина, и прогоняет бин через все BeanPostProcessor
. У обоих методов параметры абсолютно одинаковые. Разница только в порядке их вызова. Первый вызывается до init-метода, второй, после.
Порядок в котором будут вызваны BeanPostProcessor не известен, но мы точно знаем что выполнены они будут последовательно.
Важно понимать, что на данном этапе экземпляр бина уже создан и идет его донастройка. Процесс донастройки показан на рисунке ниже.
@Component
public class ClassBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
1.5. Схема создания бинов
Несмотря на кажущуюся сложность, жизненный цикл бинов крайне прост и лёгок для понимания. После создания экземпляра бина, могут понадобиться некоторые действия для того, чтобы сделать его работоспособным. Также при удалении бина из контейнера, необходима очистка.
-
Spring создает bean.
-
Spring задает значения и ссылки в поля bean.
-
Если bean реализует
BeanNameAware
, Spring передает ID бина в методsetBeanName()
. -
Если bean реализует
BeanFactoryAware
, Spring вызываетsetBeanFactory()
, передавая туда bean factory. -
Если bean реализует интерфейс
ApplicationContextAware
, Spring вызоветsetApplicationContext()
, передавая по ссылке контекст приложения. -
Если bean реализует интерфейс
BeanPostProcessor
, Spring вызывает метод бинаpostProcessBeforeInitialization()
. -
На этом происходит вызов методов init(). Если bean реализуют интерфейс
InitializingBean
, Spring вызывает методafterPropertiesSet()
.
public class CachingMovieLister {
@PostConstruct
public void populateMovieCache() {
}
}
-
Если bean реализует
BeanPostProcessor
, Spring вызовет метод бинаpostProcessAfterInitialization()
. -
В этой точке, bean готов для использования приложением и останется в контексте приложения, пока контекст не будет уничтожен.
-
На этом происходит вызов методов destroy(). Если bean реализует интерфейс
DisposableBean
, Spring вызоветdestroy()
метод.
public class CachingMovieLister {
@PreDestroy
public void clearMovieCache() {
}
}
-
Компонент перестает существовать.
1.6. IoC, DI, @Autowired
Как было описано выше, ядром Spring является контейнер Inversion of Control, функция которого создать и управлять объектами (бинами), а благодаря основной реализации Dependency Injection и связывать различные объекты между собой.
Связывать объекты между собой можно несколькими способами:
-
С помощью конструктора
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
}
-
С помощью метода (сеттер)
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
-
Через поле
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
}
По умолчанию внедрение зависимостей через методы или поля рассматриваются как обязательные зависимости. Однако, Вы можете изменить это поведение, устанавливая для required атрибута @Autowired
значение false:
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
В ситуации, когда имеются два бина для внедрения можно воспользоваться следующими аннотациями:
-
@Primary
- указывает, что текущий бин будет внедряться по умолчанию, если их несколько
@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
}
-
@Qualifier
- указывает какой бин необходимо использовать для внедрения
@Component
@Qualifier("Action")
public class ActionMovieCatalog implements MovieCatalog {
}
public class MovieRecommender {
@Autowired
@Qualifier("Action")
private MovieCatalog movieCatalog;
}
1.7. @Component
, @Service
и другие аннотации
В Spring используются следующие аннотации:
-
@Component
Аннотация для любого компонента фреймворка. -
@Repository
(Доменный слой) Аннотация показывает, что класс функционирует как репозиторий и требует наличия прозрачной трансляции исключений. Преимуществом трансляции исключений является то, что слой сервиса будет иметь дело с общей иерархией исключений от Spring (DataAccessException
) вне зависимости от используемых технологий доступа к данным в слое данных. -
@Service
(Сервис-слой приложения) Аннотация, объявляющая, что этот класс представляет собой сервис – компонент сервис-слоя. Сервис является подтипом класса@Component
. Использование данной аннотации позволит искать бины-сервисы автоматически. -
@Controller
(Слой представления) Аннотация для маркировки java класса, как класса контроллера. Данный класс представляет собой компонент, похожий на обычный сервлет (HttpServlet) (работающий с объектами HttpServletRequest и HttpServletResponse), но с расширенными возможностями от Spring Framework. -
@RestController
Аннотация аккумулирует поведение двух аннотаций@Controller
и@ResponseBody
(показывает что данный метод может возвращать собственный объект в виде xml, json и другие).
Данные аннотации используются при конфигурации приложения через аннотации.
Основной считается @Component
, общий стереотип для любого компонента, управляемого Spring. @Repository
, @Service
И @Controller
являются специализациями @Component
для более конкретных случаев применения (в настойчивости, обслуживании и презентации слоев, соответственно).
Бины, получившиеся при помощи @Repository
, дополнительно имеют обработку для JDBC Exception.
@RestController = @Controller + @ResponseBody
. Этот бин для конвертации входящих/исходящих данных использует Jackson message converter. Как правило, целевые данные представлены в json или xml.
2. Spring MVC
Spring MVC – это фреймворк для создания web-приложений на Java, в основе которого лежит шаблон проектирования MVC.
-
Spring MVC — это старый добрый MVC-фреймворк, который позволяет довольно легко писать web-сайты или web-сервисы.
-
Он прекрасно интегрируется со множеством шаблонных библиотек и библиотек преобразования данных, а также с остальной частью экосистемы Spring, такой, как Spring Boot.
-
Главным образом он позволяет вам сосредоточиться на написании своей бизнес-логики, не беспокоясь о стандартном коде для Servlet, разборе HTTP-запросов/ответов и преобразовании данных.
Паттерн MVC разделяет аспекты приложения (логику ввода, бизнес-логику и логику UI), обеспечивая при этом свободную связь между ними.
-
Model (Модель) инкапсулирует (объединяет) данные приложения, в целом они будут состоять из POJO.
-
View (Отображение, Вид) отвечает за отображение данных Модели, — как правило, генерируя HTML, которые мы видим в своём браузере.
-
Controller (Контроллер) обрабатывает запрос пользователя, создаёт соответствующую Модель и передаёт её для отображения в Вид.
Рабочий процесс обработки запроса проиллюстрирован на следующей диаграмме:
После получения HTTP-запроса DispatcherServlet выполняет следующие действия.
-
После получения HTTP-запроса DispatcherServlet даёт указание объекту HandlerMapping (обработка связывания), который вызывает следующий объект.
-
DispatcherServlet посылает запрос контроллеру и вызывает соответствующие методы. Эти методы возвращают объект, в соответствии с бизнес-логикой метода и передают название ссылки обратно в DispatcherServlet.
-
C помощью ViewResolver, DispatcherServlet подбирает необходимый вид для запроса.
-
Когда внешний вид сформирован, DispatcherServlet передаёт эти данные в модуль View, который обрабатывается браузером пользователя.
2.1. DispatcherServlet
Вся логика работы Spring MVC построена вокруг DispatcherServlet
.
DispatcherServlet
— полностью интегрированный Servlet в Spring IoC контейнер и таким образом получает доступ ко всем возможностям Spring.
При обработке запросов используется паттерн pattern-savvy reader, который распознает DispatcherServlet
как выражение из шаблона проектирования Front Controller.
DispatcherServlet
является основным контроллером Spring MVC Application. Все входящие веб-запросы проходят через DispatcherServlet
перед обработкой отдельными контроллерами Spring, то есть классами, аннотированными с помощью аннотации @Controller
.
DispatcherServlet
— это обычный Servlet (наследуется от базового класса HttpServlet
). Как и любой другой Servlet, DispatcherServlet
необходимо зарегистрировать и настроить. Сделать это можно или в файле web.xml
web.xml
<web-app>
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<url-pattern>*</url-pattern>
</servlet-mapping>
</web-app>
Либо в Java-коде переопределив метод onStartup()
интерфейса WebApplicationInitializer
:
public class WebInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(WebConfiguration.class);
DispatcherServlet servlet = new DispatcherServlet(context);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", servlet);
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
WebApplicationInitializer
— интерфейс, предоставляемый Spring MVC, который гарантирует инициализацию при старте контейнера.
Servlet диспетчера настроен как load-on-startup = 1
, что означает, что этот Servlet должен создаваться контейнером Servlets при развертывании приложения, а не при получении запроса на этот запрос.
2.2. HandlerMapping
Одним из важных интерфейсов в Spring является HandlerMapping
.
DispatcherServlet
с помощью HandlerMapping
определяет какой контроллер он должен использовать для определенного request.
По определению HandlerMapping
— интерфейс реализующийся объектами, которые определяют отображение между запросами и объектами обработчиков.
Реализации HandlerMapping
могут поддерживать перехватчики (interceptors), но не содержат их. Обработчик будет всегда обернут в экземпляре HandlerExecutionChain
, возможно в сопровождении некоторых экземпляров HandlerInterceptor
. DispatcherServlet
сначала вызывает метод preHandle()
каждого HandlerInterceptor
в заданном порядке, и в конце, внедряет обработчик, если все методы preHandle()
вернули true
.
Возможность параметризации такого отображения является мощной и необычной способностью в рамках MVC фреймворка. Например, можно написать пользовательское отображение на основе состояния session, состояние cookie или многих других переменных.
По умолчанию интерфейс HandlerMapping
в Spring MVC реализуется классом RequestMappingHandlerMapping
. Существуют другие реализации интерфейса, которые используют другие параметры для поиска контроллера, соответствующего запросу. В Spring MVC вы можете встретить реализацию интерфейса, когда применяете аннотацию @RequestMapping
@RequestMapping(value = "/", method = RequestMethod.GET)
public class Main{
public ModelAndView main() {
ModelAndView modelAndView = new ModelAndView();
return modelAndView;
}
}
2.3. Controller
DispatcherServlet
отправляет запрос контроллерам для выполнения определённых функций.
Аннотации @Controller
или @RestController
указывают, что конкретный класс является контроллером. Аннотация @RestController
равна одновременно @Controller
+ @ResponseBody
.
@ResponseBody
- дает фреймворку понять, что объект, который вы вернули из метода надо прогнать через HttpMessageConverter
, чтобы получить готовое представление к отправке клиенту.
Аннотация @RequestMapping
используется для mapping (связывания) с URL для всего класса или для конкретного метода обработчика.
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method = RequestMethod.GET)
public String printHello(ModelMap model) {
model.addAttribute("message", "Hello Spring MVC Framework!");
return "hello";
}
}
В первом случае, @RequestMapping
указывает, что все методы в данном Controller относятся к URL-адресу /hello
, а во втором как дефолтного метода для обработки HTTP-запросов GET (в данном Controller). Также можно данную аннотацию объявить над методом @RequestMapping(value = "/hello", method = RequestMethod.GET)
.
Также в контроллере может использоваться аннотация @ModelAttribute
, которая ставится над методом или в аргументах методов.
@Controller
public class HelloController {
@RequestMapping("/processForm")
public String processForm(@ModelAttribute("student") Student theStudent) {
System.out.println("theStudent :"+ theStudent.getLastName());
return "form-details";
}
@ModelAttribute("object")
public Object checkOptions() {
return new Object();
}
}
<form:form action="processForm" modelAttribute="student">
First Name : <form:input path="firstName" />
<br><br>
Last Name : <form:input path="lastName" />
<br><br>
<input type="submit" value="submit"/>
</form:form>
В зависимости от места ее применения, работать она будет по-разному. В первом случае она позволяет связать html-форму с java-объектом. А во втором случае, добавит в модель каждого метода контроллера объект с ключ-значением - object
и new Object()
.
2.3.1. @RequestParam
и @PathVariable
Часто используются аннотации @RequestParam
и @PathVariable
.
@Controller
@RequestMapping("api/test")
public class HelloController {
@GetMapping(path = "/filter")
public Test getByFilter(@RequestParam(name = "text", required = false) String text) {
return testService.getByFilter(filterTest);
}
@GetMapping(path = "/{id}")
@ResponseBody
public Test findById(@PathVariable String id) {
return testService.findById(id);
}
}
При использовании @RequestParam
передача значений будет в виде http://localhost:8080/api/test/filter?id=abc
. В этом случае данный параметр является не обязательным, но при установке атрибута required = true
(по умолчанию false
) станет обязательным для заполнения.
При использовании @PathVariable
передача значений будет в виде http://localhost:8080/api/test/abc
. В этом случае данный параметр является обязательным, но при установке атрибута required = false
(по умолчанию true
) станет не обязательным для заполнения.
2.4. ViewResolver
DispatcherServlet
с помощью ViewResolver
определяет какое представление необходимо использовать на основании полученного имени.
ViewResolver
— интерфейс, реализуемый объектами, которые способны находить представления View по имени View Name
Spring MVC поддерживает множество типов View для различных технологий отображения страницы. В том числе — JSP, HTML, PDF, Excel, XML, Velocity templates, XSLT, JSON, каналы Atom и RSS, JasperReports и другие.
По умолчанию реализацией интерфейса ViewResolver
является класс InternalResourceViewResolver
. Также могут использоваться FreeMarkerViewResolver
, BeanNameViewResolver
, ResourceBundleViewResolver
, TilesViewResolver
и многие другие.
@Configuration
public class WebConfiguration {
@Bean
public InternalResourceViewResolver internalResourceViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
public class Main{
@RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView main() {
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("userJSP", new User());
modelAndView.setViewName("index");
return modelAndView;
}
}
После того как в модель modelAndView
было записано имя представления "index"
и произошел выход из метода, то в действие включается ViewResolver. Для этого примера согласно настройкам в класс InternalResourceViewResolver
будет искать представление с именем index
, у которого префикс /WEB-INF/views/
, а суффикс .jsp
. Другими словами он должен найти представление с именем /WEB-INF/views/index.jsp
.
<html lang="">
<head>
<title>Hello Spring MVC</title>
</head>
<body>
<h2>${userJSP}</h2>
</body>
</html>
В данном случае, переменная ${userJSP}
выводит тот самый атрибут, установленный в Controller. Внутри View можно отобразить любое количество атрибутов.
Если представление найдено, то произойдет переход на эту страницу. В противном случае результат зависит от настроек реализации интерфейса ViewResolver
. По умолчанию возвращается null
, но можно возвращать имя или исключение, если вам это необходимо.
2.5. ExceptionHandler
Для обработки ошибки существует три варианта обработки:
-
для каждого контроллера
-
для каждого исключения
-
глобально
2.5.1. Уровень контроллера
Изначально основными способами обработки исключений в приложении были HandlerExceptionResolver
и аннотация @ExceptionHandler
, которая позволяла обрабатывать исключения на уровне отдельного контроллера. Для этого достаточно было объявить метод, в котором будет содержаться вся логика обработки нужного исключения, и проаннотировать его.
@RestController
public class ExampleController {
@GetMapping(value = "/testExceptionHandler", produces = APPLICATION_JSON_VALUE)
public Response testExceptionHandler() throws BusinessException {
throw new BusinessException("BusinessException in testExceptionHandler");
}
@ExceptionHandler(BusinessException.class)
public Response handleException(BusinessException e) {
return new Response(e.getMessage());
}
}
Метод handleException()
предназначен для обработки ошибок. У него есть аннотация @ExceptionHandler(BusinessException.class)
, которая говорит о том, что для последующей обработки будут перехвачены все исключения типа BusinessException
. В аннотации @ExceptionHandler
можно прописать сразу несколько типов исключений, например так: @ExceptionHandler({BusinessException.class, ServiceException.class})
.
Основной недостаток @ExceptionHandler
в том что он определяется для каждого контроллера отдельно, а не глобально для всего приложения.
Также, на уровне контроллера можно формировать ответ путём выброса исключения ResponseStatusException
.
@RestController
public class ExampleController {
@GetMapping(value = "/testResponseStatusException", produces = APPLICATION_JSON_VALUE)
public Response testResponseStatusException() {
throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "ResponseStatusException in testResponseStatusException");
}
}
Выбрасывая ResponseStatusException
можно также возвращать пользователю определённый код статуса, в зависимости от того, что произошло в логике приложения. При этом не нужно создавать собственное исключение и прописывать аннотацию @ResponseStatus
2.5.2. Уровень исключений
Для обработки ошибок на уровне исключений используется ResponseStatusExceptionResolver
. Он позволяет настроить код ответа для любого исключения с помощью аннотации @ResponseStatus
.
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public class ServiceException extends Exception {
public ServiceException(String message) {
super(message);
}
}
@RestController
public class ExampleController {
@GetMapping(value = "/testResponseStatusExceptionResolver", produces = APPLICATION_JSON_VALUE)
public Response testResponseStatusExceptionResolver() throws ServiceException {
throw new ServiceException("ServiceException in testResponseStatusExceptionResolver");
}
}
Из недостатков такого подхода — как и в предыдущем случае отсутствует тело ответа.
2.5.3. Уровень глобальной обработки
Глобально и централизованно обрабатывать исключения с помощью классов с аннотацией @ControllerAdvice
.
@ControllerAdvice
public class DefaultAdvice {
@ExceptionHandler(BusinessException.class)
public ResponseEntity<Response> handleException(BusinessException e) {
Response response = new Response(e.getMessage());
return new ResponseEntity<>(response, HttpStatus.OK);
}
}
Любой класс с аннотацией @ControllerAdvice
является глобальным обработчиком исключений, который очень гибко настраивается. Метод handleException()
имеет аннотацию @ExceptionHandler
, в которой можно определить список обрабатываемых исключений.
Так же можно в рамках @ControllerAdvice
сделать сразу несколько методов с аннотациями @ExceptionHandler
для обработки разных исключений.
3. Spring Security
Spring Security — это мощный и настраиваемый фреймворк для authentication (аутентификации) и access-control (AC/контроля доступа). Он де-факто является стандартом для безопасности приложений на основе фреймворка Spring.
Spring Security — это фреймворк, ориентированный на обеспечение как authentication (аутентификации), так и authorization (авторизации) приложений на Java. Как и во всех проектах Spring, реальная сила Spring Security заключается в том, что его можно легко расширить для удовлетворения любых требований.
Spring Security обеспечивает всестороннюю поддержку:
-
authentication (аутентификации)
-
authorization (авторизации)
-
защиты от распространенных exploits (эксплойтов), т.е. фактически предотвращает проникновение в приложение злоумышленников
Он также обеспечивает интеграцию с различными другими библиотеками, чтобы упростить его использование.
3.1. Resources
4. Spring Boot
4.1. Введение в Spring Boot
Spring Boot — самый популярный фреймворк на основе Java, построенный на базе функций Spring Framework. Он используется для создания простых и понятных в понимании standalone (автономных) и web-based (веб) приложений.
4.1.1. Что такое Spring Boot?
Spring Boot — это проект с открытым исходным кодом, разработанный командой Pivotal (команда Spring). Он построен на основе Spring Framework и предоставляет собой RAD (Rapid Application Development/Быстрая разработка приложений) на основе Spring Framework. Он комбинирует Spring Framework и third-party libraries (сторонние библиотеки), которые упрощают создание приложений и уменьшения усилия по разработке. В отличие от Spring Framework, Spring Boot не требует конфигурации на основе XML или аннотаций, поскольку он автоматически настраивает Spring и сторонние библиотеки.
Целью платформы Spring Boot является полное удаление конфигураций на основе XML и сокращение времени разработки и интеграционного тестирования.
Цели Spring Boot перечислены ниже:
-
Предложить полный Opinionated Development Approach.
-
Обеспечить большую часть функционала неявно или по умолчанию.
-
Избегать написания множества строк кода.
4.1.2. Необходимость использования Spring Boot
Некоторые из основных факторов использования среды Spring Boot перечислены ниже:
-
Он обеспечивает гибкость и простоту при разработке приложений на основе Java.
-
Он позволяет создавать менее трудоемкие приложения, так как большинство вещей управляются им по умолчанию.
-
Он не требует какой-либо конфигурации на основе XML или Java, поскольку он автоматически настраивает Spring и сторонние библиотеки.
-
Он также обеспечивает мощную batch (пакетную) обработку и гибкие транзакции базы данных.
4.1.3. Компоненты Spring Boot
As we have discussed, the Spring Boot framework is an upgraded project of the Spring framework with some additional features and components. There are four major components of Spring Boot that are listed below:
Spring Boot — это обновленный проект среды Spring с некоторыми дополнительными функциями и компонентами. Ниже перечислены четыре основных компонента Spring Boot:
-
Spring Boot Starters
-
Spring Boot AutoConfiguration
-
Spring Boot CLI
-
Spring Boot Actuator
Наряду с перечисленными выше основными компонентами в Spring Boot доступны еще два дополнительных компонента:
-
Spring Initializr
-
Spring Boot IDEs
Spring Boot Starters
Spring Boot Starters — один из основных компонентов среды Spring Boot. Он связывает более одной зависимости в группе. Это также уменьшает количество зависимостей, добавляемых вручную, путем объединения нескольких зависимостей в одну. Таким образом, он добавляет стартер вместо указания множества зависимостей.
Например, когда создается приложение Spring MVC, требуется множество зависимостей, таких как:
-
Spring Core
-
Spring Web MVC
-
Spring Web
Наряду с приведенными выше зависимостями необходимы еще некоторые зависимости. Ручное добавление зависимостей загромождает код. Spring Boot предложил решение этой проблемы.
Spring Boot упрощает задачу, поскольку добавляет только root dependency (корневую зависимость) или starter dependency (начальную зависимость). Когда добавляется starter зависимость в приложение, Spring Boot автоматически добавляет в приложение все необходимые зависимости.
Spring Boot AutoConfiguration
Spring Boot AutoConfiguration также является важным компонентом Spring Boot. Когда создается любое приложение Spring, нам требуется много кода конфигурации, например конфигурации на основе XML, Java или аннотаций. В большинстве приложений это создает много путаницы и к трате большого количества времени на это.
Поэтому для решения проблемы возник Spring Boot AutoConfiguration. Он отвечает за сокращение конфигурации Spring. При создании Spring Boot приложения нет необходимости определять какую-либо конфигурацию (на основе XML) и сократить использование конфигурации на основе аннотаций. Использование Spring Boot AutoConfiguration делает разработку приложений простой и быстрой, поскольку ее настройка не отнимает много времени.
Например, если использовать стартер spring-boot-starter-web
в приложении, Spring Boot автоматически настраивает все bean-компоненты или классы необходимые для web-приложения.
Spring Boot CLI
Spring Boot CLI (Command Line Interface) — это интерфейс командной строки для приложений на основе Spring Boot. Он позволяет запустить приложение Spring Boot с помощью CLI. Он также используется для тестирования приложений Spring Boot из командной строки. Используя интерфейс командной строки Spring Boot, также можно выполнять Groovy код, который имеет аналогичный синтаксис, подобный Java.
При запуске некоторых приложений Spring Boot через CLI он под капотом использует компоненты Spring Boot Starter и Spring Boot AutoConfiguration для решения всех зависимостей и запуску приложения.
Spring Boot Actuator
Spring Boot Actuator также является важным компонентом Spring Boot. Он также разрабатывается как подпроект (инструмент) Spring Boot. Он предоставляет множество функций для среды Spring Boot, но в основном отвечает за две его основные функции:
-
Он предоставляет (HTTP) EndPoints для управления (HTTP) для приложения на Spring Boot.
-
Он позволяет управлять работающим приложениям с помощью этих HTTP EndPoints.
Spring Boot Actuator автоматически предоставляет имя хоста как localhost
и номер порта как 8080
всякий раз, когда развертывается приложение Spring Boot с помощью интерфейса командной строки Spring Boot. Здесь обычно используются HTTP-методы GET или POST для взаимодействия с HTTP EndPoints по средствам Spring Boot Actuator.
Spring Boot Actuator в основном используется для доступа к внутренней информации приложения, такой как metrics (метрики), dump (дамп), health (работоспособность) и т.д.
Spring Initializr
Spring Initializr — это веб-интерфейс для создания, настройки и создания приложений на базе Spring. Другими словами, это инструмент, который используется для быстрого создания проекта на основе JVM. Он может создавать проекты на различных языках, таких как Java, Kotlin и Groovy. Он также предоставляет скрипт (Maven или Gradle) для создания приложений.
Spring Boot IDEs
Spring Boot поддерживает множество IDE, таких, как Eclipse, IntelliJ IDEA, Spring Tool Suite (STS) и т.д., которые используются для создания приложений.
4.1.4. Преимущества Spring Boot
Основное преимущество Spring Boot заключается в том, что он состоит из фреймворка Spring и Embedded HTTP server. Но конфигурации на основе XML и аннотаций почти нет.
Другие преимущества среды Spring Boot приведены ниже:
-
С ним легко разрабатывать приложения на основе Spring с помощью Groovy и Java.
-
Он повышает производительность и сокращает время разработки, поскольку большинство вещей управляются по умолчанию.
-
Он сводит к минимуму написание типичного длинного кода, такого как конфигурация на основе XML и аннотаций.
-
Он делает простой и плавной интеграцию Spring Boot с другими экосистемами, такими как Spring Security, Spring Data, Spring JDBC и ORM.
-
Он также предоставляет встроенные HTTP-серверы, такие, как Apache Tomcat, Apache Jetty, сервер приложений Undertow и многие другие, для развертывания и тестирования приложений на основе Spring.
-
Он также предлагает несколько плагинов для простой разработки и тестирования приложений Spring Boot с использованием инструментов сборки, таких как Maven.
4.1.5. Ограничения Spring Boot
Некоторые из ограничений Spring Boot перечислены ниже:
-
Он содержит некоторые дополнительные зависимости, которые могут быть бесполезны для конкретного приложения, поскольку используется Spring Boot Starters (root dependencies).
-
Ненужные зависимости, используемые в приложениях, приводят к огромному размеру приложения.
-
Преобразование приложений на Spring Framework в приложения на Spring Boot занимает немного времени.
4.2. Spring Boot Features
Spring Boot построена на основе Spring Framework. Фактически он является улучшенной версией проекта Spring, поэтому он способен делать то, что не может сделать Spring Framework.
Ключевые особенности среды Spring Boot перечислены ниже:
-
SpringApplication
-
Lazy Initialization
-
Admin Features
-
Security
-
Logging
-
Caching
-
Kotlin Support
-
Validation
-
JSON
-
Testing
-
Task Execution and Scheduling
4.2.1. SpringApplication
Класс SpringApplication
в основном используется для начальной загрузки и запуска приложения Spring с использованием main()
метода. В некоторых случаях можно использовать статический метод SpringApplication.run()
.
public class MyFirstSpringApp {
public static void main(String[] args) {
SpringApplication.run(MyFirstSpringApp.class, args);
}
}
По умолчанию в logs отображаются информация о запуске Spring приложения. Эти logs о запуске можно отключить, установив для spring.main.log-startup-info
значение false
в application.properties
.
4.2.2. Lazy Initialization
В Spring Boot SpringApplication
помогает lazy (отложенной/ленивой) инициализации Spring приложений. После включения lazy (отложенной/ленивой) инициализации bean-компоненты создаются по мере необходимости, а не во время запуска приложения, что приводит к более быстрому старту приложения. При включении lazy (отложенной/ленивой) инициализации в веб-приложении некоторые веб-компоненты не инициализируются до тех пор, пока не будет получен HTTP-запрос.
Включить lazy (отложенной/ленивой) инициализацию тремя способами:
-
С помощью метода
lazyInitialization()
классаSpringApplicationBuilder
. -
С помощью метода
setLazyInitialization()
классаSpringApplication
. -
С помощью свойства
spring.main.lazy-initialization=true
.
4.2.3. Admin Features
В Spring Boot можно включить функции, связанные с администрированием, указав свойство spring.application.admin.enabled=true
. Это позволит использовать задействовать интерфейс SpringApplicationAdminMXBean
на платформе MBeanServer
. Он используется для реализации wrapper services (служб-оболочек), а также для администрирования Spring Boot приложений.
4.2.4. Security
Spring Boot приложения — это приложения на основе Spring. Поэтому Spring Boot приложения очень безопасны и основаны на стратегиях безопасности Spring. Аннотация @EnableGlobalMethodSecurity
используется для добавления безопасности на уровне метода в веб-приложение.
4.2.5. Logging
Spring Boot использует Commons-logging для всех внутренних logs, который представляет собой Java-based programming model service для logging и других наборов инструментов. Некоторые конфигурации по умолчанию также предоставляются для Log4J2, Logback и Java Util Logging.
4.2.6. Caching
Кэширование поддерживается Spring Boot. Кэширование также применяется и к методам приложений, что приводит к уменьшению количества выполнений на основе информации, доступной в кеше. Spring Boot автоматически настраивает кэш, а поддержка кэширования включается с помощью аннотации @EnableCaching
.
4.2.7. Kotlin Support
Kotlin — это язык программирования, используемый для Android, серверной, мобильной кроссплатформенной и веб-разработки. Он предназначен для JVM и других платформ, которые позволяют писать короткий и простой код, обеспечивая при этом взаимодействие с другими существующими библиотеками Java.
4.2.8. Validation
Validation (валидация) автоматически поддерживается Spring Boot. Spring Boot позволяет аннотировать методы bean-компонента ограничением javax.validation
для их полей и возвращаемых значений. Целевые классы аннотируются аннотацией @Validated
и просматриваются validator (валидатором) при validation (валидации).
4.2.9. JSON
Spring Boot предлагает интеграцию с тремя основными библиотеками для JSON mapping:
-
Jackson
Jackson — это библиотека JSON по умолчанию и наиболее предпочтительная. Входит в стартерspring-boot-starter-json
. Конфигурация Jackson предоставляется по умолчанию. КомпонентObjectMapper
настраивается автоматически, когда Jackson находится в classpath. Он также предлагает несколько свойств конфигурации для настройки конфигурацииObjectMapper
. -
Gson
Конфигурация Gson предоставляется по умолчанию. Поэтому он автоматически настраивается, когда Gson находится в classpath. Существует несколько свойств конфигурацииspring.gson.*
для изменения конфигураций. Так же для управления конфигурациями используется компонентGsonBuilderCustomizer
. -
JSON-B
Автоматическая настройка для JSON-B также предоставляется по умолчанию. Компонент JSON-B настраивается автоматически, когда API для JSON-B и его реализация находятся в classpath.
4.2.10. Testing
Spring Boot предоставляет множество утилит и аннотаций, помогающих тестировать приложения. Есть два модуля, которые обеспечивают поддержку тестирования:
-
spring-boot-test
- содержит все основные элементы, -
spring-boot-test-autoconfigure
- поддерживает автоматическую настройку для тестов.
4.2.11. Task Execution and Scheduling
Если компонент Executor
отсутствует в контексте, Spring Boot автоматически настраивает ThreadPoolTaskExecutor
. В зависимости от цели можно изменить bean-компонент Executor
на ThreadPoolTaskExecutor
или определить как ThreadPoolTaskExecutor
, так и AsyncConfiguration
.
4.3. Spring Boot Architecture
Spring Boot — это расширенная версия или проект Spring Framework. Наряду с Spring Framework он также состоит из third-party libraries (сторонних библиотек) и Embedded HTTP servers. Он легко создает готовые к работе, менее трудоемкие и автономные приложения на основе Spring Framework.
Цель Spring Boot — полностью отказаться от использования конфигурации на основе XML и аннотаций в приложениях. Используя Spring Boot, можно создать приложение с минимальными усилиями (меньше времени и усилий). По умолчанию он предлагает большинство вещей, необходимых для разработки.
Spring Boot следует многоуровневой архитектуре и состоит из четырех слоев, как показано ниже.
-
Presentation Layer
-
Business Layer
-
Persistence Layer
-
Database Layer
На приведенной выше диаграмме показано, что каждый уровень архитектуры напрямую взаимодействует с уровнем, расположенным чуть выше или ниже него, благодаря workflow (рабочему процессу). Это означает, что каждый уровень зависит только от соседнего с ним уровня, поэтому, если изменяется API (не реализация этого API) одного уровня, то просто нужно обновить смежные с ним слои.
Краткое описание слоев приведено ниже.
-
Presentation layer
Это front layer или верхний слой архитектуры, так как он состоит из views (представлений). Он используется для преобразования полей JSON в объекты и наоборот, а также обрабатывает аутентификацию и HTTP запросы. После завершения аутентификации он передает ее на business layer (бизнес-уровень) для дальнейшей обработки. -
Business Layer
Обрабатывает всю бизнес-логику, а также выполняет validation и authorization, поскольку является частью бизнес-логики. Например, только администраторы могут изменять учетную запись пользователя. -
Persistence Layer
Содержит всю логику хранилища, например, запросы к базе данных приложения. Он также переводит бизнес-объекты из/в записи в базе данных. -
Database Layer
Уровень базы данных состоит из базы данных, такой как MariaDB, PostgreSQL, MongoDB и т.д. Он может содержать несколько баз данных. Все операции, связанные с базой данных, такие как CRUD (создание, чтение/извлечение, обновление и удаление), выполняются на этом уровне.
Реализация вышеописанной многоуровневой архитектуры выполняется таким образом:
HTTP-запросы или веб-запросы обрабатываются Controllers на presentation layer, services контролируют business logic, а repositories обрабатывают persistence (логику хранения). Controller может использовать несколько services, service может использовать несколько repositories, а репозиторий может использовать несколько баз данных.
4.3.1. Spring Boot Workflow
Архитектура Spring Boot основана на Spring Framework. Таким образом, он в основном использует все функции и модули Spring-подобных Spring MVC, Spring Core и т.д., за исключением того, что нет необходимости в классах DAO и DAOImpl.
На следующей диаграмме показан workflow Spring Boot.
-
Клиент делает HTTP-запрос (GET или POST).
-
Запрос пересылается Controller, который сопоставляет запрос и обрабатывает его. При необходимости он также вызывает логику Service.
-
Бизнес-логика выполняется на уровне Service, а логика выполняется с данными из базы данных, которые сопоставляются с Model или Entity class по средствам JPA.
-
Страница JSP возвращается в качестве ответа клиенту, если не произошло ошибки.