Главная страница

Хочешь, хорошо работать пользуйся Спрингом. Хочешь, чтобы работало хорошо знай его кишки. Навигация


Скачать 4.45 Mb.
НазваниеХочешь, хорошо работать пользуйся Спрингом. Хочешь, чтобы работало хорошо знай его кишки. Навигация
Дата01.06.2022
Размер4.45 Mb.
Формат файлаdocx
Имя файлаPre-project 2 and 3 module (3).docx
ТипДокументы
#562264
страница3 из 8
1   2   3   4   5   6   7   8
1   2   3   4   5   6   7   8




16. Как устроена (ApplicationEvent) обработка событий в ApplicationContext?

ApplicationContext, управляет жизненным циклом бинов. В процессе своей работы он вызывает целый ряд, событий (ContextStoppedEvent, ContextStartedEvent и т.д.). Обработка этих событий обеспечивается классом ApplicationEvent и интерфейсом ApplicationListener. И когда бин имплементирует интерфейс ApplicationListener, то каждый раз, когда вызывается то или иное событие, бин получает об этом информацию.

Существует целый ряд стандартных событий в Spring Framework:

1) ContextStartedEvent — Это событие публикуется, когда ApplicationContext запущен через метод start() интерфейса ConfigurableApplicationContext. После получения этого события мы можем выполнить необходимые нам действия (например, записать то-то в базу данных и т.д.).

2) ContextRefreshedEvent — Это событие публикуется, когда ApplicationContext обновлён или инициализирован. Оно может быть вызвано использованием метода refresh() интерфейса ConfigurableApplicationContext.

3) ContextStoppedEvent — Это событие публикуется, когда ApplicationContext остановлен методом stop() интерфейса ConfigurableApplicationContext. Мы также можем дать команду выполнить определённую работу после получения этого события.

4) ContextClosedEvent — Публикуется, когда ApplicationContext закрыт методом close() интерфейса ConfigurableApplicationContext. Закрытие контекста – это конец файла. После этого он не может быть перезапущен или обновлен.

5) RequestHandledEvent — Это специальное событие, которое информирует нас о том, что все бины HTTP-запроса были обслужены (ориентирован на веб).

Бонусом служит то, что Spring позволяет нам создавать свои собственные события и обрабатывать их. Обработка событий в Spring однопоточна, а значит, если событие опубликовано, то все процессы будут блокированы, пока все адресаты не получат сообщение.

17. Что такое ApplicationContext? (Это главный интерфейс во фреймворке Spring)

ApplicationContext — это главный интерфейс в Spring-приложении, который предоставляет информацию о конфигурации приложения. Он доступен только для чтения во время выполнения, но может быть перезагружен. Число классов, реализующих ApplicationContext интерфейс, доступны для различных параметров конфигурации и типов приложений.

ApplicationContext предоставляет:

1) Фабричные методы бина для доступа к компонентам приложения;

2) Возможность загружать файловые ресурсы в общем виде;

3) Возможность публиковать события и регистрировать обработчики на них;

4) Возможность работать с сообщениями с поддержкой интернационализации;

5) Наследование от родительского контекста.
Допустим, для нашей программы надо использовать 3 объекта: котика, собачку и попугайчика.

И у нас есть куча классов с кучей методов, где иногда нам нужен для метода котик, а для другого метода — собачка, а иногда у нас будут методы, где нужен котик и попугайчик (например метод для кормёжки котика, хе-хе). Мы можем в main-е сначала создать эти три объекта, а потом их передавать в наши классы, а уже изнутри классов — в нужные нам методы... И так по всей программе. А если ещё и представить, что периодически мы захотим менять список принимаемых параметров для наших методов (ну решили переписать что-то или добавить функциональности) — то нам придется делать довольно много правок по коду если надо будет что-то поменять. А теперь если представить, что таких объектов у нас не 3, а 300? Для этого в Spring существует ApplicationContext.
ApplicationContext – это обёртка над мапой (которая хранит объекты), где сделаны методы, чтобы в каких-то случаях доставать объекты по их имени (ключ), а в других случаях — по классу (значение).

ApplicationContext — содержит набор бинов (объектов). Обращаясь к нему — мы можем получить нужный нам бин (объект) по его имени, или по его типу, или ещё как-то.

Кроме того, мы можем попросить Spring самого сходить поискать в своём ApplicationContext нужный нам бин и передать его в наш метод(Dependency Injection).

Н апример, если у нас был такой метод:

Spring когда вызывал этот метод — передавал в него объект нашего котика из своего контекста. Теперь мы решаем, что нашему методу кроме котика нужен ещё и попугайчик.

Т еперь, когда будет вызывать метод — Spring сам поймет, что сюда надо передать котика и попугайчика, сходит к себе в контекст, достанет эти два объекта и передаст их в наш метод.

Передав спрингу бразды правления нашей программой (Inversion of Control) — мы так же переложили на него ответственность за создание Java объектов (аналог new) и передачу их в наши методы (Dependency Injection), которые он будет вызывать.

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



В данном примере у нас два контекста. Первый контекст является родителем второго контекста. Второй контекст имеет все бины, которые лежат в первом контексте + может иметь свои бины, которых нет в первом контексте.

18. Для чего существует такое количество реализаций ApplicationContext? (конфигурация приложения)

Для того чтобы Spring создал контекст с экземплярами классов, ему нужно предоставить дополнительную информацию — метаданные, из каких классов/объектов состоит ваше приложение, как они создаются, какие у них есть зависимости и т. д. Spring Context + метаданные = работающее приложение.

Существует три способа конфигурации приложения (указания спрингу какие именно объекты нам нужны для работы). Они отличаются друг от друга именно тем, каким способом задаются метаданные и где хранится эта конфигурация:
1) При помощи xml файлов/конфигов; - самый низкоприоритетный способ.



— ClassPathXmlApplicationContext — метаданные конфигурируются XML-файлом(-ами) и они лежат в classpath, т. е. в ресурсах модуля;

— FileSystemXmlApplicationContext — метаданные тоже конфигурируются XML-файлом(-ами), но они находятся где-то в файловой системе, например, /etc/yourapp/spring-context.xml;

— GenericGroovyApplicationContext — когда конфигурация представляет собой файл с кодом Groovy

2) При помощи java-конфигов; - если при помощи АК нет возможности правильно настроить все возможные бины.

AnnotationConfigApplicationContext(JavaConfig.class) — конфигурация через аннотации с указанием класса (или массива классов), помеченного аннотацией @Configuration

3) Автоматическая конфигурация(АК). - наиболее приоритетный способ, которому стоит отдавать предпочтение. Можно использовать внутри кода аннотации @Component, @Service, @Repository, @Controller для указания классов в качестве спринг бинов.

— AnnotationConfigApplicationContext(”package.name”) — с указанием пакета для сканирования — метаданные конфигурируются с помощью аннотаций прямо на классах.

— StaticApplicationContext.

19. Что такое интерфейс BeanPostProcessor?

BeanPostProcessor - позволяет настраивать наши бины до того, как они попадают в контейнер (напомню, что контейнер — это, по сути, простая HashMap коллекция).

У этого интерфейса 2 метода:

• Object postProcessBeforeInitialization(Object bean, String beanName)

• Object postProcessAfterInitialization(Object bean, String beanName)

А между ними вызывается init метод.

20. Что такое интерфейс BeanFactoryPostProcessor?

BeanFactoryPostProcessor - позволяет настраивать BeanDefinitions, до того, как будут созданы эти бины.

Этот интерфейс имеет один единственный метод:

• postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)

Этот метод запустится на этапе, когда другие бины ещё не созданы, и есть только BeanDefinitions.
Spring поставляет несколько полезных реализаций BeanFactoryPostProcessor, например, читающий property-файлы и получающий из них свойства бинов.

Также можно написать собственную реализацию BFPP.

21. Что такое BeanDefinitions?

BeanDefinitions – это объект, который хранит в себе информацию о конфигурационных метаданных бина.

22. Что такое интерфейс ClassPathBeanDefinitionScanner?

ClassPathBeanDefinitionScanner - не является ни BeanPostProcessor-ом, ни BeanFactoryPostProcessor-ом

• Он ResourceLoaderAware

• Создаёт BeanDefinitions из всех классов, над которыми стоит @Component, или другая аннотация, включающая @Component

BEANS В НАЧАЛО ДОКУМЕНТА

1. Что такое бин? Как они создаются?

Б ин (bean) — это обычный объект какого-то класса. Разница в том, что бинами принято называть объекты, которые управляются Spring-ом и живут внутри его Dependency Injection -контейнере . Эти объекты создаются с помощью конфигурационных метаданных, которые указываются в контейнере . Метаданные нужны управляющему контейнеру для получения следующей информации:

- Как создать бин;

- Информацию о жизненном цикле бина;

- Зависимости бина.

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

Для получения экземпляра бина используется ApplicationContext. IoC контейнер управляет жизненным циклом Spring бина, областью видимости и внедрением.

Singleton-бины обычно создаются сразу при сканировании.

Prototype-бины обычно создаются только после запроса.

Чтобы указать способ инициализации, можно использовать аннотацию @Lazy.

Она ставится на @Bean-методы, на @Configuration-классы, или на @Component-классы.

В зависимости от параметра(true или false), который принимает аннотация, инициализация будет или ленивая, или произойдет сразу. По умолчанию(т.е. без указания параметра) используется true.

2. Свойства определяющие бин?

1) class – Этот атрибут является обязательным и указывает конкретный класс Java-приложения, который будет использоваться для создания бина.

2) name – Уникальный идентификатор бина. В случае конфигурации с помощью xml-файла, вы можете использовать свойство “id” и/или “name” для идентификации бина.

3) scope – Это свойство определяет область видимости создаваемых объектов.

4) constructor-arg – Определяет конструктор, использующийся для внедрения зависимости в XML-файле.

5) properties – Определяет свойства внедрения зависимости в XML-файле.

6) initialization method – Здесь определяется метод инициализации бина.

7) destruction method – Метод уничтожения бина, который будет использоваться при уничтожении контейнера, содержащего бин.

8) autowiring mode – Определяет режим автоматического связывания при внедрении зависимости.

9) lazy-initialization mode – Режим ленивой инициализации даёт IoC контейнеру команду создавать экземпляр бина при первом запросе, а не при запуске приложения.

3. Виды бинов EJB?

1) Entity Bean – бин, цель которого — хранить некоторые данные. В логику такого бина встроен механизм сохранения себя и своих полей в базу данных. Такой объект может быть уничтожен, а потом воссоздан из базы заново. Но кроме хранения данных у него нет никакой логики.

2) Session Bean – это функциональный бин. У каждого Session Bean есть своя функция. Один делает одно, другой другое. Такие бины работают с другими объектами и бинами, а не со своими данными.

Session Beans делятся на две категории.

- Stateless Session Bean – это бин, который не хранит во внутренних переменных важных данных, нужных для его работы. Такой бин можно уничтожить, а затем заново создать, и он будет выполнять свою функцию, как и раньше.

- Statefull Session Bean – это бин, который хранит у себя внутри данные, которые использует при работе. Если мы вызываем методы этого бина, то в каждом следующем вызове он может использовать часть данных, переданных ему в предыдущих. И всё равно этот бин – это не то же самое, что обычный объект.

4. Является ли Bean потокобезопасным?

По умолчанию бин задаётся как синглтон в Spring. Таким образом все публичные переменные класса могут быть изменены одновременно из разных мест. Так что - нет, не является. Однако поменяв область действия бина на request, prototype, session он станет потокобезопасным, но это скажется на производительности.

5. Как получить бин?

Для извлечения бина из контекста используется следующий подход:



6. Что такое жизненный цикл Bean?

Ж изненный цикл Spring бина – время существования класса. Spring бины инициализируются при инициализации Spring контейнера и происходит внедрение всех зависимостей. Когда контейнер уничтожается, то уничтожается и всё содержимое. Если нам необходимо задать какое-либо действие при инициализации и уничтожении бина, то нужно воспользоваться методами init() и destroy(). Для этого можно использовать аннотации @PostConstruct и @PreDestroy().
Spring не управляет полным жизненным циклом bean-компонента со Scope prototype. Контейнер создаёт, настраивает и иным образом собирает объект-prototype и передаёт его клиенту без дальнейшей записи этого экземпляра-prototype. То есть нам необходимо самостоятельно вызывать метод destroy() после того, как бин prototype выполнил свои функции. Иначе это приведёт к дорогостоящим потерям ресурсов.

В некоторых отношениях роль IoC контейнера Spring в отношении bean-объекта с прототипом является заменой new оператора Java. Все управление жизненным циклом после этой точки должно выполняться клиентом.

7. Наследование бинов?

Определение бина может содержать множество различных конфигураций (конструктор, методы инициализации и уничтожения и т.д.).

- Наследованием (когда мы говорим о бинах) называется ситуация, когда “бин-потомок” перенимает (наследует) конфигурационные данные от своего “бина-родителя”. Бин-наследник может переопределять (override) некоторые унаследованные свойства и добавлять свои собственные, если это потребуется.

- При этом важно учитывать тот факт, что наследование бинов в Spring не имеет ничего общего с наследованием классов в Java. Сам принцип наследования, тем не менее, остаётся тем же.

- Другими словами, Вы можете определить некий шаблонный бин и, наследуясь от него, добавлять необходимый функционал в “бины-потомки”.


8. Чем отличается Spring Bean, JavaBean и POJO классы?

P OJO (plain-old-Java-object) – это класс запущенный с базовым JDK, без поддержки других сторонних библиотек.

Все JavaBeans — это POJO, но не все POJO — это JavaBeans. POJO не имеет строгого определения.

Пример класса POJO.
JavaBean— это объект Java, который удовлетворяет определенным соглашениям программирования:

1) Класс JavaBean должны реализовать Serializable или externalizable;

2) Класс JavaBean должен иметь публичный конструктор (без аргументов);

3) Все свойства JavaBean должны иметь публичные методы setter и getter (соответственно);

4 ) Все переменные экземпляра JavaBean должны быть приватными.
Spring bean – это объект, который создаётся, настраивается и управляется контейнером Spring Framework. Компоненты Spring определяются в файлах конфигурации Spring (или, в последнее время, с аннотациями), создаются экземплярами контейнеров Spring и затем вводятся в приложения.

Spring Beans не всегда являются JavaBeans. Spring beans может не реализовывать интерфейс java.io.Serializable, и может иметь аргументы в своих конструкторах и т. д. Это основное различие между JavaBeans и Spring Beans.

9. Что такое DTO? (Data Transfer Object)

DTO объект - Java объект, который не содержит методы. Он может содержать только поля, геттеры/сеттеры, и конструкторы. Его цель: пересылать данные между процессами для уменьшения количества вызовов методов.

Data Transfer Object - объект, передающий данные. Данные - это и есть поля в классе.

Реальный пример - игра шашки. У вас есть объект Checker(шашка). У него не должно быть методов, только поля.

Если у Checker есть методы(переопределенный equals и compare(к примеру)), но это методы из Object и он всё ещё может считаться DTO объектом, т.к. он сделан только для того, что бы хранить данные(координаты шашки).

10. Что такое связывание бинов? Какие подходы к связыванию бинов?

Когда запускается программное приложение, совместно работают сразу несколько объектов (бинов). Также они могут использоваться независимо от других объектов.

Чтобы заставить бины работать вместе, их связывают через введение зависимостей в Spring (привязки). Когда запускается приложение на основе Spring, контекст приложения загружает определения компонентов или объектов из файла конфигурации и связывает их вместе.

Существует два подхода к привязке bean-компонентов в среде Spring:

- Привязка через XML.

constructor-arg – Определяет конструктор, использующийся для внедрения зависимости в XML-файле.

properties – Определяет свойства внедрения зависимости в XML-файле.

- Привязка через классы Java. (@Autowired) См. далее.

11. Какие есть способы связывания бинов?

Существует два способа привязки bean-компонентов в среде Spring:

1) Вручную, объявив bean-компоненты с помощью Dependency Injection (DI).

2) Позволить контейнеру Spring самостоятельно связать необходимые компоненты.

Последний способ известен как автоматическая привязка. При этом контейнеру Spring нужно указать, как он должен их связывать:
1) autowirebyName – автоматическое связывание по имени бина. Контейнер Spring ищет в XML файле бин с указанным именем. И если находит бин с таким же именем – производит автоматическое связывание.

2) autowirebyType – автоматическое связывание по типу. В этом случае контейнер Spring ищет совпадение по типу. В случае, если он находит – происходит автоматическое связывание. Если в XML-файле определены несколько бинов с таким типом, то мы получаем исключение (exception).

3) autowirebyconstructor – здесь всё происходит так же, как и при использовании режима ‘byType’, с тем отличием, что поиск идёт по аргументам конструктора. Если в XML-файле находится несколько таких бинов – мы получаем ошибку (error).

4) autodetect– в этом режиме сначала происходит связывание в режиме ‘constructor’, а затем (если автосвязывание не произошло) в режиме ‘byType’.



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