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

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


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

1. Конфигурирование с помощью аннотаций (Annotations)?

- @Required - может применяться к setter’ам.

- @Autowired - может применяться к сеттерам, обычным методам, конструкторам и свойствам.

- @Qualifier - Этот вид аннотаций используется вместе с аннотациями Autowired когда возможна путаница при связывании (непонятно, с каким бином необходимо связать) и определяет конкретный бин

- JSR-250 Annotations - Spring Framework поддерживает аннотации основанные на JSR-250 (@PostConstruct, @PreDestroy и т.д.)

2. Конфигурирование с помощью Java? @Configuration и @Bean отличия?

- @Configuration – эта аннотация, прописанная перед классом, означает, что класс может быть использован контейнером Spring IoC как конфигурационный класс для бинов.

- @Bean – аннотация @Bean, прописанная перед методом, информирует Spring о том, что возвращаемый данным методом объект должен быть зарегистрирован, как бин.

Также используется @Scope после @Bean для ограничения области видимости.

ВНИМАНИЕ: Создание компонентов при помощи @Bean-методов возможно только в классах, помеченных аннотацией @Confuguration. В остальных случаях используются аннотации создания компонента @Component или аннотаций, наследующих её, таких как @Service, @Repository или @Controller.

3. В чём разница между @Bean и @Component?

-@Bean используется в конфигурационных классах Spring. Он используется для непосредственного создания бина.

-@Component используется со всеми классами, которыми должен управлять Spring. Когда Spring видит класс с @Component, Spring определяет этот класс как кандидата для создания bean.

4. Свойства аннотации @Bean?

destroyMethod — указывает на метод обратного вызова. Метод находится в бине.

initMethod — указывает на метод обратного вызова. Метод находится в бине.

name — имя бина. По умолчанию именем бина является имя метода.

value — алиас для name()

5. Какие аннотации используются в Spring? (тут только часть)

@Controller - класс фронт контроллера в проекте Spring MVC.

@RequestMapping - позволяет задать шаблон маппинга URI в методе обработчике контроллера.

@ResponseBody - позволяет отправлять Object в ответе. Обычно используется для отправки данных формата XML или JSON.

@PathVariable - задаёт динамический маппинг значений из URI внутри аргументов метода обработчика.

@Autowired - используется для автоматического связывания зависимостей в spring beans.

@Qualifier - используется совместно с @Autowired для уточнения данных связывания, когда возможны коллизии (например, одинаковых имен\типов).

@Service - указывает что класс осуществляет сервисные функции.

@Scope - указывает область действия bean через “request”, “prototype”, “session”, “singleton”, “global-session”.

@Configuration, @ComponentScan и @Bean - для java based configurations.

@Aspect, @Before, @After,@Around, @Pointcut и др. AspectJ аннотации для настройки aspects и advices.

@Bean используется для определения компонентов с кастомной логикой.

6. Какая разница между аннотациями @Component, @Repository, @Service и @Controller в Spring?

- @Component используется для указания класса в качестве компонента Spring. При использовании поиска аннотаций, такой класс будет сконфигурирован как Spring bean. Родитель @Repository, @Service и @Controller.

- @Repository указывает, что класс используется для работы с поиском, получением и хранением данных. Аннотация используется для реализации шаблона DAO.

- @Service указывает, что класс является сервисом для реализации бизнес-логики (на самом деле не отличается от Component, он просто помогает разработчику указать смысловую нагрузку класса).

- @Controller специальный тип класса, применяемый в MVC приложениях. Обрабатывает запросы и часто используется с аннотациями типа @RequestMapping, @GetMapping, @PostMapping.

Вы не можете поменять местами эту аннотацию с @Service или @Repository. Потому что, диспетчер сканирует аннотированные классы @Controller и ищет @RequestMapping и другие аннотации.

7. @RequestMapping, @GetMapping, @PostMapping и т.д. Поясни?

@RequestMapping - аннотация может использоваться как на уровне класса, так и на уровне метода. В большинстве случаев на уровне метода приложения предпочтут использовать один из новых вариантов использования на уровне метода HTTP: @GetMapping, @PostMapping, @PutMapping, @DeleteMapping, или @PatchMapping.
@GetMapping — HTTP - GET используется для получения (или чтения) конкретными методами обработчика.

@GetMapping —идентична @RequestMapping(method = RequestMethod.GET) и является его ярлыком.

@PostMapping — HTTP - POST используется для создания новых ресурсов конкретными методами обработчика.

@PostMapping — идентична @RequestMapping(method = RequestMethod.POST) и является его ярлыком.

@PutMapping — HTTP - PUT используется для обновления ресурса конкретными методами обработчика.

@PutMapping — идентична @RequestMapping(method = RequestMethod. PUT) и является его ярлыком.

Ресурсом является всё у чего есть имя. Пользователь, изображение, предмет, майка, голодная собака.

С остальными методами по аналогии.

8. @RequestParam, @ModelAttribute, @PathVariable?

1) @ RequestParam для извлечения параметров запроса, параметров формы и файлов из запроса.

Параметры метода, помеченные @RequestParam, являются обязательными по умолчанию. @RequestParam может указывать значения по умолчанию , если параметр запроса отсутствует или пуст, используя атрибут defaultValue. Ползём сюда.

2 ) @ModelAttribute используется в качестве аргументов метода, он привязывает к нему параметры запроса. Связывает данные формы с бобом POJO, атрибут модели заполняется данными из отправленной формы. Удобно для создания объектов.

3 ) @PathVariable в отличии от @RequestParam может быть только один на всю форму. Часто используется с id в качестве параметра. Указывает что данный параметр будет получен из адресной строки. Удобно для редактирования и удаления какого-либо объекта.

9. В чём отличие между @Component и @ComponentScan?

@Component и @ComponentScan предназначены для разных целей

@Component помечает класс в качестве кандидата для создания Spring бина.

@ComponentScan указывает, где Spring искать классы, помеченные аннотацией @Component или его производной.

10. Хорошо, компоненты создали, дальше, что с ними делать? Внедряем! @Autowired

Компоненты можно внедрять в другие компоненты, самый распространённый пример — внедрение репозитория в контроллер. Внедрять зависимости можно через свойство(поле) класса, через конструктор и сеттеры.

1) С амый простой, но не очень удобный для понимания, @Autowired.

Контекст Spring находит класс, помеченный аннотацией @Controller, создаёт объект этого класса, находит свойство, помеченное аннотацией @Autowired и присваивает указанному свойству @Component нужного класса, находящийся в контексте Spring.

Тут может произойти две ошибки: в контексте Spring не окажется @Component класса SimpleBean, либо в контексте окажется более одного @Component класса SimpleBean, в таком случае применяется @Qualifier.

DI через поле не рекомендуется использовать, т.к. для этого применяется рефлексия, снижающая производительность.

2 ) Внедрение через конструктор значительно удобнее, так как при тестировании даёт возможность вручную создать объект класса и передать ему мок вместо реального компонента.

В таком случае свойства(поля) класса можно сделать .Фактически это даёт возможность передавать несколько внедряемых компонентов в конструктор.

DI через конструктор считается самым лучшим способом, т.к. для него не надо использовать рефлексию, а также он не имеет недостатков DI через сеттер.

DI через конструктор может приводить к циклическим зависимостям. Чтобы этого избежать, можно использовать ленивую инициализацию бинов или DI через сеттер.

3) Внедрение через сеттер аналогично внедрению через конструктор с той разницей, что свойство класса нельзя сделать final.


11. Разница между @Controller и @RestController? Как вернуть страницу в контроллере? Как вернуть данные?

@Controller: эта аннотация - всего лишь специализированная версия @Component, и она позволяет автоматически обнаруживать классы контроллеров на основе сканирования classpath.

@RestController: эта аннотация является специализированной версией @Controller, которая автоматически добавляет @Controller и @ResponseBody аннотации, поэтому нам не нужно добавлять @ResponseBody к нашим методам отображения.

Основная разница между традиционным Spring MVC контроллером и RESTfull веб-сервис контроллером заключается в способе создания тела HTTP ответа. MVC контроллер опирается на технологию View, а RESTfull веб сервис контроллер возвращает объект, который представляется в HTTP ответе в виде JSON или XML. @RestController превращает помеченный класс в Spring-бин. Этот бин для конвертации входящих/исходящих данных использует Jackson message converter.
@Controller – Возвращает страницу и данные при помощи шаблонизаторов JSP вроде Thymeleaf.

@ RestController – Возвращает данные. Используется с JSON или XML. Позволяет применять технологии без перезагрузки веб страниц, на основе JS.

Для того, чтобы настроить @RestController на возвращение JSON или XML используются Jackson зависимости.

При отправке данных с фронта в рестконтроллер нужно в заголовке(header) указать тип возвращаемого/отправляемого тела запроса.

Например, ContentType или accept: "application/json"

12. Что делают аннотации @RequestBody и @ResponseBody?

Каждый раз, когда отправленный запрос попадает в @RequestBody или ответ попадает в @ResponseBody, они проходят по всем зарегистрированным HttpMessageConverter, ища первое совпадение, которое соответствует заданному типу и классу mime, а затем использует его для фактического преобразования либо в POJO класс, либо в указанный формат для отображения в браузере, например JSON.

1) @ RequestBody – аннотация, указывающая, что параметр метода контроллера должен быть привязан к телу HTTP-запроса, в соответствии с заголовком HTTP-запроса (content-Type: Контент). Преобразуется в класс JAVA с помощью подходящего HttpMessageConverter. Используется в POST и PUT методах. Данные представлены в формате JSON или XML, а не в виде обычных пар "ключ-значение".

2 ) @ResponseBody – аннотация может быть помещена в метод и используется для возврата и записи объекта прямо в тело HTTP-ответа, в соответствии с заголовком HTTP-запроса. (Accept: Контент) через соответствующие HttpMessageConverter. После преобразования в указанный формат он записывается в область данных тела объекта Response.

Что такое HttpMessageConverter? (Применяется только в RestController-ах)

HttpMessageConverter конвертирует запрос в объект и наоборот. Spring имеет несколько реализаций этого интерфейса, мы можем создать свою. В этом случае DispatcherServlet не использует Model и View.

Список конвертеров:

- BufferedImageHttpMessageConverter — конвертирует BufferedImage в(из) код изображения.

- Jaxb2RootElementHttpMessageConverter — конвертирует xml в(из) объект, помеченный jaxb2 аннотациями. Регистрируется, если jaxb2 находится в classpath.

- MappingJackson2HttpMessageConverter — конвертирует JSON в(из) объект. Регистрируется, если Jackson 2 находится в classpath.

- StringHttpMessageConverter — конвертирует все медиа-файлы в text/plain.

13. Почему иногда мы используем @ResponseBody, а иногда @ResponseEntity?

ResponseEntity необходим, только если мы хотим кастомизировать ответ, добавив к нему статус ответа. Во всех остальных случаях будем использовать @ResponseBody.

Стандартные HTTP коды статусов ответов, которые можно использовать.

200 — SUCCESS, 201 — CREATED, 404 — RESOURCE NOT FOUND, 400 — BAD REQUEST, 401 — UNAUTHORIZED,

500 — SERVER ERROR

Для @ResponseBody единственные состояния статуса это SUCCESS(200), если всё ок и SERVER ERROR(500), если произошла какая-либо ошибка.

Допустим мы что-то создали и хотим отправить статус CREATED(201). В этом случае мы используем ResponseEntity.

14. В чём разница между RequestEntity, ResponseEntity и HttpEntity? (Они используются в RestTemplate)

HttpEntity можно использовать для создания как RequestEntity, так и ResponseEntity, так как он является их родителем.

RequestEntity расширяет HttpEntity и добавляет в запрос дополнительную информацию о методе HTTP и URI.

ResponseEntity позволяет нам добавить собственный HTTP ответ, включая заголовок (при помощи ResponseEntity.HeadersBuilder), текст, код состояния/статус и тело к объекту ответа (при помощи ResponseEntity.BodyBuilder). Он ограничен только отправкой ответа.

RestTemplate это специальный клиент для отправки запросов в Spring (что-то вроде встроенной программы POSTMAN). Он предоставляет удобные API для легкого вызова конечных точек(эндпойнтов) REST’а в одну строку. В нём так же применяются все эти сущности.

15. Какие вы знаете различные @Scope() у Spring Bean? (2 в обычном приложении и 5 в веб приложении)

Область видимости указывается с помощью аннотации @Scope на @Bean методах.

Бины с разными @Scope не совсем между собой совместимы и это может приводить к ошибкам.

1) singleton – может быть создан только один экземпляр бина (для каждого контейнера IoC). Этот тип используется спрингом по умолчанию, если не указано другое. Следует осторожно использовать публичные свойства класса, т.к. они не будут потокобезопасными.

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

2) prototype – создаётся новый экземпляр объекта при каждом запросе. Контейнер не управляет жизненным циклом этого объекта, он его только создаёт. Уничтожаем мы его самостоятельно чтобы освободить ресурсы, если забудем, то за нас это сделает сборщик мусора. Prototype Scope не потокобезопасный, т.к. не гарантирует что один и тот же экземпляр будет вызываться только в 1 потоке.

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

3) request – аналогичен prototype, но название служит пояснением к использованию бина в веб приложении. Создаётся новый экземпляр при каждом HTTP request. То есть каждый HTTP-запрос имеет свой собственный экземпляр компонента, после получения ответа он уничтожается. Действителен только в контексте веб-приложения.

4) session – новый бин создаётся в контейнере при каждой новой HTTP сессии. Содержит в себе множество бинов с request компонентами, которые постоянно, то создаются, то уничтожаются. Уничтожается в конце пользовательской сессии. Действителен только в контексте веб-приложения.

5) application – область применения одного бина к жизненному циклу ServletContext. Действителен только в контексте веб-приложения.

6) websocket – область применения одного бина к жизненному циклу WebSocket. Действителен только в контексте веб-приложения.

7) global-session – используется для создания глобальных бинов на уровне сессии для Portlet приложений.

16. Немного про взаимодействие singleton и prototype компонентов?

Когда вы используете одноэлементные (singleton) компоненты с зависимостями от прототипов (prototype), имейте в виду, что зависимости разрешаются во время создания экземпляра.

Предположим, что вы хотите, чтобы bean-объект с singleton областью многократно получал новый экземпляр bean-объекта prototype во время выполнения, но увы, мы не можем внедрить bean-компонент prototype в наш синглтон-компонент, поскольку это внедрение происходит только один раз, когда контейнер Spring создаёт экземпляр синглтон-компонента, а также разрешает и внедряет его зависимости. Экземпляр прототипа является единственным экземпляром, который когда-либо поставляется в бин с singleton областью действия.

17. Прокси в Scope? (указывается вторым параметром)

Мы можем попросить spring создать специальный прокси, который с одной стороны будет иметь (внутри себя) scope singleton и, таким образом, быть совместимым со всеми scopes, с другой стороны этот прокси будет определять требуемый в данном контексте исполнения бин с меньшим временем жизни (например session бин) и передавать все вызовы ему.

Попросить spring создать прокси можно разными путями. Во-первых, в аннотацию @Scope можно передать proxyMode=INTERFACES который создадут для класса proxy, основанный на интерфейсах, или proxyMode=TARGET_CLASS, который реализует класс или сгенерирует специальный отдельный класс.

Копаем тут!

18. Как создать свой Scope класс(область)?

Д ля этого нужно имплементировать интерфейс Scope и переопределить 5 его методов.
1) get(String name, ObjectFactory objectFactory) - Возвращает объект с заданным именем из базовой области, создаёт его, если он не найден в базовом механизме хранения. Является единственным обязательным методом для переопределения.

2) getConversationId() - Возвращает идентификатор диалога для текущей базовой области, если таковая имеется.

3) registerDestructionCallback(String name, Runnable callback) - Регистрирует обратный вызов, который будет выполняться при уничтожении указанного объекта в области (или при уничтожении всей области, если область не уничтожает отдельные объекты, а только полностью завершается).

4) remove(String name) - Удаляет объект с определённым именем из базовой области.

5) resolveContextualObject(String key) - Разрешает контекстный объект для данного ключа, если таковой имеется.
Ч тобы контейнер Spring знал о вашей новой области, вам нужно зарегистрировать его с помощью метода registerScope в экземпляре ConfigurableBeanFactory.

Первый параметр, используется для идентификации/указания области по её уникальному имени. Второй параметр, scope, является фактическим экземпляром пользовательской реализации Scope, которую вы хотите зарегистрировать и использовать.

Смотрим сюда!

19. Spring @Transactional что это?

Изначально транзакции управляются самим разработчиком (императивно).

Такой способ контроля за транзакциями придает прозрачности коду, но есть несколько недостатков:

1 ) Много повторяющегося кода и склонность к ошибочному поведению.

2) Любая ошибка имеет очень большое влияние.

3) Ошибки трудно отладить и воспроизвести.

4) Усложняет удобочитаемость кода.

5) Что делать если этот метод вызывает другой метод с транзакциями?
C аннотацией @Transactional, эти проблемы решаются и пример можно упростить (декларативно):

Такой код намного удобен и читаем, рекомендуется использовать именно такой подход для управления транзакциями в Spring. Есть только один минус – непонятно что под капотом.

Одна из главных ловушек в Spring - если вы вызываете @Transactional-метод из нетранзакционного метода в том же классе, то @Transactional игнорируется (если мы не используем AOP плетение).

Благодаря этой аннотации у нас нет кучи повторяющихся rollback, commit и begin по всей программе и все транзакции, отделены от логики вашего бизнеса. Это одна из концепций Aspect Oriented Programming.(AOP).

Аннотацию @Transactional можно добавлять в класс (метод класса) или интерфейс (метод интерфейса).
Сервис — лучшее место для размещения @Transactional, сервисный уровень должен содержать поведение для взаимодействия с пользователем, которое логически переходит в транзакцию.

Существует много CRUD-приложений, у которых нет существенной бизнес-логики, имеющих сервисный уровень, который просто передаёт данные между контроллерами и объектами доступа к данным, что не является полезным. В этих случаях мы можем поместить аннотацию транзакции на уровень DAO.

Рассмотрим другой пример, когда ваш уровень обслуживания может вызывать два разных метода DAO для выполнения операций БД. Если ваша первая операция DAO завершилась неудачей, остальные две могут быть переданы, и вы закончите несогласованное состояние БД. Аннотирование на сервисном уровне может спасти вас от таких ситуаций.

Нужно аннотировать только конкретные классы (и методы конкретных классов) аннотацией @Transactional. Дело в том, что при использовании прокси-классов или аспектов, аннотированные транзакцией интерфейсы не распознаются инфраструктурой проксирования и сплетения. Транзакционное поведение не будет применяться и вас уволят через неделю.

20. Какие есть атрибуты у @Transactional?

Для того, чтобы некоторые методы класса (помеченные аннотацией @Transactional) имели разные настройки атрибутов, разместите аннотацию на уровне метода, чтобы переопределить настройки атрибутов уровня класса.



1) DEFAULT: использовать уровень изоляции, установлен по умолчанию.

2) READ_COMMITTED (чтение фиксированных данных): Постоянная, указывающая, что “грязное” чтение предотвращено; могут возникать неповторяющееся чтение и фантомное чтение.

3) READ_UNCOMMITTED (чтение незафиксированных данных): Этот уровень изоляции указывает, что транзакция может считывать данные, которые ещё не удалены другими транзакциями.

4) REPEATABLE_READ (повторяемость чтения): Постоянная, указывающая на то, что “грязное” чтение и неповторяемое чтение предотвращаются; может появляться фантомное чтение.

5) SERIALIZABLE (упорядочиваемость): Постоянная, указывающая, что “грязное” чтение, неповторяемое чтение и фантомное чтение предотвращены.

Очень хорошая статья тут.

21. Как вы решаете какой бин инжектить, если у вас несколько подходящих бинов. @Primary или @Qualifier?

- Если есть бин, который вы предпочитаете большую часть времени по сравнению с другими, то используйте @Primary, и используйте @Qualifier для нестандартных сценариев.

- Если все бины имеют одинаковый приоритет, мы всегда будем использовать @Qualifier

- Если бин надо выбрать во время исполнения программы, то эти аннотации вам не подойдут. Вам надо в конфигурационном классе создать метод, пометить его аннотацией @Bean, и вернуть им требуемый бин.

22. Как получить данные из файла .property? (3 способа)



  1. При помощи аннотации @PropertySource.

  2. @ConfigurationProperties и @Configuration

@ConfigurationProperties определяет файл свойств для загрузки.

@Configuration создает компонент на основе переменных файла конфигурации.

  1. @Value

Вы можете использовать @Value для загрузки переменных из, application.properties если вы будете использовать это значение в одном месте, но, если вам нужен более централизованный способ загрузки этих переменных @ConfigurationProperties, это лучший подход.

4) xml способ:

23. Можно ли создать свои аннотации в Spring?

Мы можем создать свои собственные мета-аннотации, которые собирают несколько других Spring аннотаций, чтобы уменьшить мета-шаблонность в вашем коде. Такой подход применяется когда у нас много классов с большим колличеством одинаковых аннотаций. В общем делаем оболочку для аннотаций и применяем её вместо них.

Создали свою аннотацию: где newImplMyTestAnnotation — ваша новая имплементация.

А ннотация @Retention позволяет указать жизненный цикл аннотации.

1) SOURCE — видна только в исходном коде. Когда мы компилируем, в байткоде ничего не будет, в рантайме тоже ничего о ней не знаем.

2) CLASS — (по умолчанию) видна в скомпилированном файле. Аннотация в байткод попасть должна, но через Reflection в рантайме мы её считать не сможем, т.е. присутствует только в момент выполнения компилятора.

3) RUNTIME — видна в процессе выполнения и можно считать через Reflection.

Аннотация @Target указывает, что именно мы можем пометить этой аннотацией: это может быть поле, метод, тип и т.д. Иными словами область её применения.

- ElementType.ANNOTATION_TYPE — наша аннотация может присутствовать только над другими аннотациями

- ElementType.CONSTRUCTOR — аннотация может присутствовать только над конструкторами

- ElementType.FIELD — аннотация может присутствовать только над полем класса (любым)

- ElementType.LOCAL_VARIABLE — аннотация может присутствовать только над локальной переменной метода

- ElementType.METHOD — аннотация может присутствовать только над методом

- ElementType.PACKAGE — аннотация может присутствовать только над пакетом (распространяется на все классы в пакете)

- ElementType.PARAMETER — аннотация может присутствовать только над аргументом метода

- ElementType.TYPE — аннотация может присутствовать только над классом или интерфейсом

@Inherited — наследуется потомками (аннотация будет распространяться на всех потомков)

@Documented — в Javadoc попадает информация о том, что данный класс помечен данной аннотацией

Когда мы написали свою аннотацию, чтобы она отработала нам нужно в XML для неё указать свой BeanPostProcessor, иначе не отработает, т.к. про неё никто не знает.



либо добавить @Component над MyTestAnnotationBeanPostProcessor, указав его как бин.

Загляни сюда! и сюда!

24. Что такое циркулярная(круговая, циклическая) зависимость бинов?

Циркулярная зависимость является круговой ссылкой, то есть два или более бобов держат друг друга и в конечном итоге образуют замкнутый цикл. Например, A зависит от B, B зависит от C, а C зависит от A. Муж зависит от жены, а жена от мужа. Это означает, что для компиляции проекта A вы должны сначала скомпилировать проект B, но вы не можете этого сделать, поскольку B требует, чтобы A был скомпилирован. Это проблема, которую вызывают циклические зависимости.

Существует два вида зависимости:

1) Круговая зависимость конструктора (невозможно решить).

2) Циклическая зависимость атрибутов поля.

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

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

Циклические зависимости могут вызывать утечку памяти , не позволяя некоторым примитивным автоматическим сборщикам мусора (использующим подсчет ссылок) освобождать неиспользуемые объекты.

О том как с ними бороться я адекватной информации не нашёл. Видимо легче предотвратить чем устранить.

Можно посмотреть этот ролик.

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

1. Что такое AOP (Аспектно-ориентированное программирование)?

AOP —парадигма программирования, которая является дальнейшим развитием процедурного и объектно-ориентированного программирования (ООП). Эта методология призвана снизить время, стоимость и сложность разработки ПО. В современном ПО, как правило, можно выделить определенные части, или аспекты, отвечающие за функциональность, реализация которой рассредоточена по коду программы, но состоит из схожих кусков кода. Около 70% времени в проектах тратится на сопровождение и внесение изменений в готовый программный код.

AOP — это парадигма программирования, основанная на идее разделения функциональности для улучшения разбиения программы на модули.

Аспектно-ориентированное программирование выросло из осознания того, что в типовых программах на объектно-ориентированных языках часто представлена функциональность, которая не вмещается естественно в один или даже в несколько тесно связанных программных модулей. Такую функциональность называют "сквозной" (англ. scattered, разбросанная или tangled, переплетённая), её реализация рассыпана по различным модулям программы. Сфера действия АОП охватывает пространство проблем, непосильных для объектно-ориентированных и процедурных языков. Оно предлагает элегантные пути для реализации задач, решение которых сдерживалось из-за фундаментальных ограничений программирования.
АОП дополняет объектно-ориентированное программирование, обогащая его другим типом модульности, который позволяет локализовать код реализации "сквозной" логики в одном модуле. Такие модули обозначаются термином аспекты. За счет отделения аспектно-ориентированного кода работа со "сквозными" отношениями упрощается. Аспекты в системе могут изменяться, вставляться, удаляться на этапе компиляции.

Тема очень объёмная и понять её можно ВОТ ЗДЕСЬ! и ЗДЕСЬ!

2. Основные концепции AOP в SPRING?

Все языки АОП предоставляют средства для выделения сквозной функциональности в отдельную сущность. Так как AspectJ является родоначальником этого направления, используемые в нём концепции распространились на большинство языков АОП.

Использование аспектно-ориентированного программирования помогает следовать принципу разделения ответственности (separation of concerns), что положительно сказывается на многих характеристиках разрабатываемой информационной системы, некоторыми из которых являются следующие:

- Более эффективный процесс создания системы;

- Более качественная реализация;

- Повышенные возможности тестирования;

- Улучшенная модульность системы.

Основные понятия:

1) Точка соединения (joinpoint) — точка в программе, где существует возможность выполнить дополнительный код средствами АОП (где следует применить совет.). Различные реализации АОП имеют различные возможные точки соединения, таковыми могут являться момент вызова методов класса или обращений к полям объекта. Точки соединения могут, в свою очередь, содержать другие точки соединения.

2) Совет (advice) —класс, реализующий сквозную функциональность. Средство оформления кода, который должен быть вызван из точки соединения. Существуют различные типы советов: выполняемые до точки соединения, после или вместо неё.

3) Срез (pointcut) — набор точек соединения (joinpoint), которые выбраны для исполнения в ней сквозной функциональности. Срез определяет, подходит ли данная точка соединения к данному совету (advice).

4) Аспект (aspect) — модуль или класс, реализующий сквозную функциональность. Аспект изменяет поведение остального кода, применяя совет в точках соединения, определённых некоторым срезом. Аспект состоит из среза (pointcut) и реализующего сквозную функциональность совета (advice). В Spring для этого используется также понятие advisor.

5) Внедрение или введение (introduction) —процесс модификации объекта путем добавления дополнительных полей и /или методов, а также изменение структуры класса и/или изменение иерархии наследования для добавления функциональности аспекта в инородный код. Внедрение также может быть использовано для реализации объектом интерфейса без явного указания этого в классе объекта. Обычно реализуется с помощью некоторого метаобъектного протокола.

6) Связывание (weaving) – связывание аспектов с объектами для создания новых, «расширенных» объектов.

7) Цель или целевой объект (target) – объект, являющийся результатом связывания (weaving), то есть реализующий первоначальную бизнес-логику плюс сквозная функциональность, выполненная одним или несколькими аспектами.

3. А теперь тоже самое только простыми словами!

Итак, АОП — аспектно-ориентированное программирование — это парадигма, направленная на повышение модульности различных частей приложения за счёт разделения сквозных задач. Для этого к уже существующему коду добавляется дополнительное поведение, без изменений в изначальном коде.

Иными словами, мы как бы навешиваем сверху на методы и классы дополнительную функциональность, не внося поправки в модифицируемый код.
Ключевой единицей в ООП является “объект”, а ключевой единицей в АОП – “аспект”. В качестве примера “аспекта” можно привести безопасность, кэширование, логирование и т.д.

Внедрений зависимостей (DI) позволяет нам отделять объекты приложения друг от друга. АОП, в свою очередь, позволяет нам отделять сквозные проблемы (cross-cuttings) от объектов, к которым они относятся.

Функции, которые охватывают несколько точек приложения называются сквозной проблемой (cross-cutting concerns), и они отделены от бизнес-логики приложения.
Модуль AOP в Spring обеспечивает нас такими сущностями, как “перехватчики” (interceptors) для перехвата приложения в определённые моменты. Например, когда выполняется определённый метод, мы можем добавить какую-то функциональность (к примеру, сделать запись в лог-файл приложения) как до, так и после выполнения метода.


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