pp_2_модуль. Application context & dependency injection что такое бин
Скачать 266.51 Kb.
|
APPLICATION CONTEXT & DEPENDENCY INJECTION Что такое бин? JavaBeans — классы в языке Java, написанные по определённым правилам. Они используются для объединения нескольких объектов в один (англ. bean — фасоль, кофейное зерно) для удобной передачи данных. Spring-бины − это классы, созданием экземпляров которых и установкой в них зависимостей управляет контейнер фреймворка Spring. Бины предназначены для реализации бизнес-логики приложения. Виды бинов? Лет 10 назад массовое распространение получила концепция EJB – Enterprise Java Beans. Entity Bean – бин, цель которого — хранить некоторые данные. В логику такого бина встроен механизм сохранения себя и своих полей в базу данных. Такой объект может быть уничтожен, а потом воссоздан из базы заново. Но кроме хранения данных у него нет никакой логики. Session Bean – это функциональный бин. У каждого Session Bean есть своя функция. Один делает одно, другой другое. Такие бины работают с другими объектам и бинами, а не со своими данными. Session Beans делятся на две категории. Stateless Session Bean – это бин, который не хранит во внутренних переменных важных данных, нужных для его работы. Такой бин можно уничтожить, а затем заново создать, и он будет выполнять свою функцию, как и раньше. Statefull Session Bean – это бин, который хранит у себя внутри данные, которые использует при работе. Если мы вызываем методы этого бина, то в каждом следующем вызове он может использовать часть данных, переданных ему в предыдущих. И все равно этот бин – это не то же самое, что обычный объект Область видимости бинов (scope) - singleton Определяет один единственный бин для каждого контейнера Spring IoC - prototype Позволяет иметь любое количество экземпляров бина. - request Создаётся один экземпляр бина на каждый HTTP запрос. Касается исключительно ApplicationContext. - session Создаётся один экземпляр бина на каждую HTTP сессию. Касается исключительно ApplicationContext.- global-session Создаётся один экземпляр бина на каждую глобальную HTTP сессию. Касается исключительно ApplicationContext. Чем бин отличается от POJO-класса?? POJO (англ. Plain Old Java Object) — «простой Java-объект в старом стиле», простой Java-объект, не унаследованный от какого-то специфического объекта и не реализующий никаких служебных интерфейсов сверх тех, которые нужны для бизнес-модели. Spring Bean — это, по сути, объект, управляемый Spring. В частности, это объект, который создается, настраивается и иным образом управляется контейнером Spring Framework . Spring Bean определяются в файлах конфигурации Spring (или, в последнее время, с помощью аннотаций), создаются контейнерами Spring, а затем внедряются в приложения. Соответственно, сложно найти что-то общее между ними. Если же речь идет о различиях между POJO и JavaBean, то сравнение выглядит более уместным, в частности: Все JavaBeans являются POJO, но не все POJO являются JavaBeans. Serializable, т.е. они должны реализовывать интерфейс Serializable. Тем не менее, некоторые POJO, которые не реализуют интерфейс Serializable, называются POJO, потому что Serializable является маркерным интерфейсом и, следовательно, не несет большого бремени. Поля должны быть приватными. Это необходимо для обеспечения полного контроля над полями. Поля должны иметь геттеры и/или сеттеры. В бине должен быть конструктор без аргументов. К полям обращаются только конструкторы или геттеры-сеттеры. Что такое Inversion of Control и как Spring реализует этот принцип? Ключевая особенность приложения, написанного на Spring, состоит в том что большую часть объектов создаем не мы, а Spring. Мы лишь конфигурируем классы (с помощью аннотаций, либо в конфигурационном XML), чтобы «объяснить» фреймворку Spring, какие именно объекты он должен создать за нас, и полями каких объектов их сделать. Spring управляет созданием объектов и потому его контейнер называется IoC-контейнер. IoC расшифровывается как Inversion of Control. А объекты, которые создаются контейнером и находятся под его управлением, называются бинами. В общем на вход контейнер Spring принимает: Наши обычные классы (которые впоследствии будут бинами). Конфигурацию (неважно как именно ее задавать – либо в специальном файле XML, либо с помощью специальных аннотаций). А на выходе он производит объекты – бины. То есть экземпляры классов, созданные в соответствии с конфигурацией и внедренные куда нужно (в другие бины). После этого никакие операторы new нам не понадобятся, мы будем работать в классе-бине с его полями-бинами так, будто они уже инициированы. Конечно, не со всеми полями, а только с теми, которые сконфигурированы как бины. Остальные инициализируются как обычно, в том числе с помощью оператора new. Для чего существует такое количество ApplicationContext? Чтоб можно было задавать разные способы конфигурирования? Сразу определим, что ApplicationContext — это главный интерфейс в Spring-приложении, который предоставляет информацию о конфигурации приложения. У Spring есть 4 способа конфигурации: Xml конфигурация - ClassPathXmlApplicationContext(”context.xml”); Groovy-конфигурация- GenericGroovyApplicationContext(”context.groovy”); Конфигурация через аннотации с указанием пакета для сканирования - AnnotationConfigApplicationContext(”package.name”); JavaConfig - конфигурация через аннотации с указанием класса (или массива классов) помеченного аннотацией @Configuration - AnnotationConfigApplicationContext(JavaConfig.class). @Autowired,_где_можно_ставить_и_какие_есть_отличия_Плюсы_и_минусы_каждого_способа._Почему_не_рекомендуется_связывать_через_поле'>@Autowired, где можно ставить и какие есть отличия? Плюсы и минусы каждого способа. Почему не рекомендуется связывать через поле? Начиная с Spring 2.5, в фреймворке были введены управляемые аннотациями dependency injection . Основная аннотация этой функции – @Autowired. В приложении может быть использовано 3 варианта внедрения зависимостей: через конструктор Cчитается самым лучшим способом, т.к. для него не надо использовать рефлексию, а также он не имеет недостатков других методов. Инъекция через конструкторы хороша для обязательных зависимостей — тех, которые требуются для корректной функциональности объекта. Передавая их через конструктор, можно быть уверенным в том, что объект полностью готов к использованию с момента создания. Поля, присвоенные в конструкторе, также могут быть final, что позволяет объекту быть полностью неизменным или как минимум защищает необходимые поля. через сеттеры Внедрение через конструктор может приводить к циклическим зависимостям. Чтобы этого избежать, можно использовать ленивую инициализацию бинов или внедрение через сеттер. Сеттеры следует использовать для инъекций опциональных зависимостей. Класс должен быть способен функционировать, даже если они не были предоставлены через аннотацию над полем Не рекомендуется использовать, т.к. для этого применяется рефлексия, снижающая производительность. При внедрении прямо в поле нет прямого способа создания экземпляра класса со всеми необходимыми зависимостями. Что такое Dependency Injection? Внедрение зависимости (англ. Dependency injection, DI) — процесс предоставления внешней зависимости программному компоненту. Является специфичной формой «инверсии управления» (англ. Inversion of control, IoC), когда она применяется к управлению зависимостями. Какие бины будут использоваться для настройки приложения? Аннотация @Configuration, прописанная перед классом, означает, что класс может быть использован контейнером Spring IoC как конфигурационный класс для бинов. Аннотация @Bean, прописанная перед методом, информирует Spring о том, что возвращаемый данным методом объект должен быть зарегистрирован, как бин. Аннотация @ComponentScan("path") задает путь по которому спринг будет искать классы для создания бинов. SPRING MVC Как получить данные из файла .properties? .properties — файловое расширение для файлов, которые используются в основном в технологиях Java для хранения конфигурационных параметров программы (логин, пароль, URL и пр.). Каждый параметр сохраняется парой двух переменных строчной типа, одна сохраняет имя параметра (так называемый ключ), а другой сохраняет значение. Каждая строка файла .properties, как правило, хранит значения одного параметра. Для получения указанных свойств обычно используют класс Environment и его методы (н-р: private Environment env; env.getProperty()), перед этим необходимо сообщить название файла. Конфигурационный класс Spring: @PropertySource("classpath:db.properties") XML-файл: Чистая Java: java.util.Properties Как запустить Спринг-приложение из-под сервера Tomcat? Общая логика действий: Внести изменения в POM.XML ( war ) Сделать .jar файлы доступными (перенести в папку webapp/WEB-INF/lib) Скомпилировать и задеплоить War файл Запустите сервер Tomcat (startup.bat) Тестирование (http://localhost:8888/books/list) Что такое Artifacts? Артефакты - в широком смысле это некие объекты создаваемые в ходе разработки ПО, например схемы классов, объектные коды, документация, инструкции, иконки, картинки и проч. все что сопровождает процесс разработки. В узком смысле - в смысле Intellij IDEA это некая выходная сборка вашего проекта. В общем случае их может быть несколько: jar для десктопа и .war для веба ну и т.д. Для каждого артефакта можно определить правила сборки, развертывания, запуска и т.д. Есть еще артефакты в смысле Maven - это все тот же архив, но предназначенный для деплоймента на репозиторий maven В самом собственно Java нет понятия артефакта - артефакт продукт среды/средства разработки. В чем отличие артефакта war от war exploded? По сути, war артефакт — упакованный в архив проект, только уже скомпилированный, и в котором изменена структура папок так, чтобы его можно было выкладывать уже напрямую на Tomcat. war exploded - то же самое, только в незаархивированном виде. Какая разница между аннотациями @Component, @Repository и @Service в Spring? Все они определяют бины Spring. Однако между ними всё же есть разница. @Component — универсальный компонент @Repository — компонент, который предназначен для хранения, извлечения и поиска. Как правило, используется для работы с базами данных. @Service — фасад для некоторой бизнес логики Пользовательские аннотации, производные от @Component, могут добавлять специальную логику в бинах. Например, бины, получившиеся при помощи @Repository, дополнительно имеют обработку для JDBC Exception Как выглядит структура MVC-приложения? Model (Модель) инкапсулирует (объединяет) данные приложения. Контроллер управляет запросами пользователя ( HTTP, GET или POST запросы, когда пользователь нажимает на элементы интерфейса для выполнения различных действий). Его основная функция — вызывать и координировать действие необходимых ресурсов и объектов, нужных для выполнения действий, запрашиваемых пользователем. Контроллер: Обрабатывает запросы от пользователя Обменивается данными с моделью Показывает пользователю правильное представление Переадресовывает пользователя на другие страницы View это представление приложения, например страницы html. View используется для отображения данных приложения пользователю. Spring MVC поддерживает несколько поставщиков View(они называются шаблонизаторы) — JSP, JSF. Чем контроллер отличается от сервлета? Сервлет принимает запросы от пользователя и перенаправляет их на определенный контроллер. Сервлет представляет специальный тип классов Java, который выполняется на веб-сервере и который обрабатывает запросы и возвращает результат обработки. Контроллер это часть архитектурного шаблона MVC отвечающая за обработку входящих запросов. В контексте Spring MVC в качестве сервлета выступает dispatcher servlet, реализующий паттерн FrontController, который принимает все входящие запросы и перенаправляет их на соответствующие контроллеры. В приложении Spring MVC может существовать произвольное количество экземпляров DispatcherServlet, предназначенных для разных целей (например, для обработки запросов пользовательского интерфейса, запросов веб-служб REST и т.д.). Каждый экземпляр DispatcherServlet имеет собственную конфигурацию WebApplicationContext, которая определяет характеристики уровня сервлета, такие как контроллеры, поддерживающие сервлет, отображение обработчиков, распознавание представлений, интернационализация, оформление темами, проверка достоверности, преобразование типов и форматирование и т.п. Какая основная зависимость фреймворка Спринг? Почему во многих сборках она не указывается явно? Spring-core. Не указывается потому, что она включается потому что включается по умолчанию. Как вернуть страницу в контроллере? Как вернуть данные? Вернуть страницу можно по ее названию. Вернуть данные с помощью модели (н-р, model.addAttribute("var_name", data)) Model — интерфейс, ModelMap его реализация.. ModelAndView является контейнером для пары, как ModelMap и View. @GetMapping("/goToViewPage") public ModelAndView passParametersWithModelAndView() { ModelAndView modelAndView = new ModelAndView("viewPage"); modelAndView.addObject("message", "Baeldung"); return modelAndView; } ДРУГОЕ Уметь рассказать про принципы работы Spring По сути Spring Framework представляет собой просто контейнер внедрения зависимостей и может быть рассмотрен как коллекция меньших фреймворков или фреймворков во фреймворке. Большинство этих фреймворков может работать независимо друг от друга, однако они обеспечивают большую функциональность при совместном их использовании. Эти фреймворки делятся на структурные элементы типовых комплексных приложений: Inversion of Control - контейнер (Core): делегированное (фреймворку) конфигурирование компонентов приложений и управление жизненным циклом Java-объектов. Фреймворк аспектно-ориентированного программирования (AOP): работает с функциональностью, которая не может быть реализована возможностями объектно-ориентированного программирования на Java без потерь. Фреймворк доступа к данным (Data Access/Integration): работает с системами управления реляционными базами данных на Java-платформе, используя JDBC- и ORM-средства и обеспечивая решения задач, которые повторяются в большом числе Java-based environments. Фреймворк управления транзакциями: координация различных API управления транзакциями и инструментарий настраиваемого управления транзакциями для объектов Java. Фреймворк MVC (Web): каркас, основанный на HTTP и сервлетах, предоставляющий множество возможностей для расширения и настройки (customization). Фреймворк удалённого доступа: конфигурируемая передача Java-объектов через сеть в стиле RPC, поддерживающая RMI, CORBA, HTTP-based протоколы, включая web-сервисы (SOAP). Фреймворк аутентификации и авторизации: конфигурируемый инструментарий процессов аутентификации и авторизации, поддерживающий много популярных и ставших индустриальными стандартами протоколов, инструментов, практик через дочерний проект Spring Security (ранее известный как Acegi). Фреймворк удалённого управления: конфигурируемое представление и управление Java-объектами для локальной или удалённой конфигурации с помощью JMX. Фреймворк работы с сообщениями (Messaging): конфигурируемая регистрация объектов-слушателей сообщений для прозрачной обработки сообщений из очереди сообщений с помощью JMS, улучшенная отправка сообщений по стандарту JMS API. Тестирование (test): каркас, поддерживающий классы для написания модульных и интеграционных тестов. Связывание бинов и их жизненный цикл. Через следующие этапы проходит каждый отдельно взятый бин: Инстанцирование объекта. Техническое начало жизни бина, работа конструктора его класса; Установка свойств из конфигурации бина, внедрение зависимостей; Пре-инициализация – метод postProcessBeforeInitialization() интерфейса BeanPostProcessor; Инициализация. Разные способы применяются в таком порядке: • Метод бина с аннотацией @PostConstruct из стандарта JSR-250 (рекомендуемый способ); • Метод afterPropertiesSet() бина под интерфейсом InitializingBean; • Init-метод. Для отдельного бина его имя устанавливается в параметре определения initMethod. В xml-конфигурации можно установить для всех бинов сразу, с помощью default-init-method; Пост-инициализация – метод postProcessAfterInitialization() интерфейса BeanPostProcessor. Основные паттерны Spring Вот некоторые известные паттерны, используемые в Spring Framework: Proxy (Заместитель) - AOP/Remoting Прокси предоставляет заместителя для другого объекта, чтобы контролировать доступ к нему. Singleton (Одиночка) Гарантирует, что в памяти будет существовать только один экземпляр объекта, который будет предоставлять сервисы. Factory (Фабрика) Этот паттерн позволяет инициализировать объект через публичный статический метод, называемый фабричным методом. Template (Шаблон) Этот паттерн широко используется для работы с повторяющимся бойлерплейт (шаблонным) кодом (таким как, закрытие соединений и т. п.). Model View Controller (Модель-Представление-Контроллер) Front Controller (Контроллер запросов) Используется для обеспечения централизованного механизма обработки запросов, так что все запросы обрабатываются одним обработчиком. Этот обработчик может выполнить аутентификацию, авторизацию, регистрацию или отслеживание запроса, а затем передать запрос соответствующему контроллеру. View Helper (Вспомогательный компонент представления) Отделяет статическое содержимое в представлении, такое как JSP, от обработки бизнес-логики. Dependency injection и Inversion of control (IoC) (Внедрение зависимостей и инверсия управления) Service Locator (Локатор служб) ServiceLocatorFactoryBean сохраняет информацию обо всех бинах в контексте. Когда клиентский код запрашивает сервис (бин) по имени, он просто находит этот компонент в контексте и возвращает его. Observer-Observable (Наблюдатель) Определяет зависимость "один-ко-многим" между объектами, чтобы при изменении состояния одного объекта все его подписчики уведомлялись и обновлялись автоматически. Context Object (Контекстный объект) Инкапсулирует системные данные в объекте-контексте для совместного использования другими частями приложения без привязки приложения к конкретному протоколу. Настройка контекста и инициализация бинов. Алгоритм инициализации контекста: XmlBeanDefinitionReader/AnnotatetedBeanDefinitionReader сканирует конфиги и создает BeanDefinition для каждого из бинов. Сохранение всех сгенерированных BeanDefinition в HashMap. BeanFactory обрабатывает HashMap и предварительно подготавливает BeanPostProcessor’ы. Генерация бинов в IoC-контейнер. Настройка бинов с помощью 2х методов BBP (postProcessBeforeInitialization и postProcessAfterInitialization). |