Wikipedia: The Spring Framework is an open source application framework and inversion of control container for the Java platform.
Например, xml-конфигурация (а конфигурация - это указания для spring, какие компоненты создать и как их собрать) может выглядеть так:
Тогда создание контейнера (если xml-файлы - это файлы конфигурации):
DI через setter'ы:
DI через конструктор:
Контейнер проверяет конфигурацию всех бинов сразу после создания контейнера. Но созданы зависимости будут только при создании бина. По-умолчанию, бины являются Singleton и pre-instantiated. То есть, буду созданы тоже сразу после создания контейнера (контекста).
Beans scopes: singleton, prototype (создается новый объект при каждом обращении), request / session / global session - имеют смысл только если контекст имеет отношение к web.
Это Container, так как Spring управляет жизненным циклом всех объектов контейнера: создает их и связывает (wiring) их друг с другом.
Это Framework, Spring позволяет создавать и конфигурировать сложные приложения из простых компонент, предоставляя гибкие и эффективные реализации многих необходимых сервисов.
1. DI и IoC Фаулер считает одним и тем же, просто DI - более подходящий термин. Паттерн DI предоставляет компоненту внешнюю зависимость (вместо того, чтобы захардкодить её). То есть мы сообщаем объекту о его зависимостях вместо того, чтобы он сам о них знал.
Предыстория: Мы стараемся использовать интерфейсы, например tree.getFruits(), но где мы создаем объект tree? Если в классе, который его использует, то получается, что класс зависит не только от интерфейса ITree, но и от конкретной реализации, скажем AppleTree. А если кто-то захочет использовать BananaTree?
Решение: Иметь некий объект - assembler - который будет инициализировать поле tree конкретной реализацией (через сеттер или конструктор).
2. Из чего состоит Spring (картинка взята с docs.spring.io) :

3. IoC Container создает бины и внедряет (injects) в них зависимости. BeanFactory обеспечивает конфигурацию и управление объектами. ApplicationContext (интерфейс, расширяющий BeanFactory) добавляет resource handling (для I18n), event publication, AOP features. в Spring это тип BeanFactory. Можно сказать, что BeanFactory - основная функциональность, ApplicationContext - добавляет enterprise-specific функциональность. Как оно выглядит:

Configuration Metadata может быть xml-based, annotation-based или java-based.
Это Framework, Spring позволяет создавать и конфигурировать сложные приложения из простых компонент, предоставляя гибкие и эффективные реализации многих необходимых сервисов.
1. DI и IoC Фаулер считает одним и тем же, просто DI - более подходящий термин. Паттерн DI предоставляет компоненту внешнюю зависимость (вместо того, чтобы захардкодить её). То есть мы сообщаем объекту о его зависимостях вместо того, чтобы он сам о них знал.
Предыстория: Мы стараемся использовать интерфейсы, например tree.getFruits(), но где мы создаем объект tree? Если в классе, который его использует, то получается, что класс зависит не только от интерфейса ITree, но и от конкретной реализации, скажем AppleTree. А если кто-то захочет использовать BananaTree?
Решение: Иметь некий объект - assembler - который будет инициализировать поле tree конкретной реализацией (через сеттер или конструктор).
2. Из чего состоит Spring (картинка взята с docs.spring.io) :

3. IoC Container создает бины и внедряет (injects) в них зависимости. BeanFactory обеспечивает конфигурацию и управление объектами. ApplicationContext (интерфейс, расширяющий BeanFactory) добавляет resource handling (для I18n), event publication, AOP features. в Spring это тип BeanFactory. Можно сказать, что BeanFactory - основная функциональность, ApplicationContext - добавляет enterprise-specific функциональность. Как оно выглядит:

Configuration Metadata может быть xml-based, annotation-based или java-based.
Например, xml-конфигурация (а конфигурация - это указания для spring, какие компоненты создать и как их собрать) может выглядеть так:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="..." class="..."> <!-- collaborators and configuration for this bean go here --> </bean> <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl"> <property name="accountDao" ref="accountDao"/> <property name="itemDao" ref="itemDao"/> <!-- additional collaborators and configuration for this bean go here --> </bean> <!-- more bean definitions go here --> </beans>
Тогда создание контейнера (если xml-файлы - это файлы конфигурации):
// create and configure beans ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"services.xml", "daos.xml"}); // retrieve configured instance PetStoreService service = context.getBean("petStore", PetStoreService.class);
DI через setter'ы:
<bean id="exampleBean" class="examples.ExampleBean"> <!-- setter injection using the nested <ref/> element --> <property name="beanOne"><ref bean="anotherExampleBean"/></property> <!-- setter injection using the neater ref attribute --> <property name="beanTwo" ref="yetAnotherBean"/> <property name="integerProperty" value="1"/> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/>
DI через конструктор:
<bean id="exampleBean" class="examples.ExampleBean"> <!-- constructor injection using the nested <ref/> element --> <constructor-arg> <ref bean="anotherExampleBean"/> </constructor-arg> <!-- constructor injection using the neater ref attribute --> <constructor-arg ref="yetAnotherBean"/> <constructor-arg type="int" value="1"/> </bean> <bean id="anotherExampleBean" class="examples.AnotherBean"/>
Контейнер проверяет конфигурацию всех бинов сразу после создания контейнера. Но созданы зависимости будут только при создании бина. По-умолчанию, бины являются Singleton и pre-instantiated. То есть, буду созданы тоже сразу после создания контейнера (контекста).
Beans scopes: singleton, prototype (создается новый объект при каждом обращении), request / session / global session - имеют смысл только если контекст имеет отношение к web.
4. Spring MVC
Как и в других Web фреймворках, Spring использует сервлет DispatcherServlet для управления всеми входящими запросами (этот шаблон еще называют Front controller).
web.xml:
В web.xml файле, мы определили servlet mapping (соотнесли), который реагирует на любой URL, заканчивающийся на .htm. Если .htm встретилось, мы переходим на DispatcherServlet. Этот сервлет анализирует входящие запросы URL и определяет, какому контроллеру передать управление.
Как оно выглядит в графическом виде? (Взято с Spring Recipes)
DispatcherServlet = Front Controller
Handler Mapping = Map of url and controllers
Создание applicationContext: ContextLoaderListener это ServletListener. Он будет вызван при создании ServletContext'а для этого web-приложения. При вызове внутри ContextLoaderListener создается ApplicationContext и загружается конфигурационный xml (задается через context-param в web.xml). В этом конфигурационном файле (по логике вещей) не должно быть бинов связанных с web-слоем).
DispatcherServlet в его init методе тоже создает ApplicationContext, который должен загружать Controller'ы, ViewResolver'ы, MappingHandler'ы.
Бины из web tier видят бины уровня middle-tier, но не наоборот.
В простых случаях можно обойтись только контекстом из DispatcherServlet, но если есть что-то из нижеперечисленного, то не получится:
- несколько DispatcherServlet, которые разделяют сервисы
- legacy/non-Spring servlets, которым нужны бины
- есть сервлетные фильтры (Spring Security's DelegatingFilterProxy, OpenEntityManagerInViewFilter, ...)
web.xml:
<servlet> <servlet-name>MVC Dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>MVC Dispatcher</servlet-name> <url-pattern>*.htm</url-pattern> </servlet-mapping>
В web.xml файле, мы определили servlet mapping (соотнесли), который реагирует на любой URL, заканчивающийся на .htm. Если .htm встретилось, мы переходим на DispatcherServlet. Этот сервлет анализирует входящие запросы URL и определяет, какому контроллеру передать управление.
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Если нет * в url-pattern, то контейнер знает, что реквесты без path info (без .xxx) должны быть направлены DispatcherServlet'у. То есть, когда придет запрос на xxx.jsp, DispatcherServlet не будет реагировать.
Как оно выглядит в графическом виде? (Взято с Spring Recipes)
DispatcherServlet = Front Controller
Handler Mapping = Map of url and controllers
5. Контексты
Spring позволяет определить несколько контекстов. Они образуют иерархию предок-потомок. Контекст applicationContext.xml определяет бины для всего web-приложения. Контекст spring-servlet.xml определяет бины для одного Spring сервлета (за все контроллеры отвечает этот контекст). Бины из spring-servlet.xml могут обращаться к бинам из applicationContext.xml, но не наоборот.Создание applicationContext: ContextLoaderListener это ServletListener. Он будет вызван при создании ServletContext'а для этого web-приложения. При вызове внутри ContextLoaderListener создается ApplicationContext и загружается конфигурационный xml (задается через context-param в web.xml). В этом конфигурационном файле (по логике вещей) не должно быть бинов связанных с web-слоем).
DispatcherServlet в его init методе тоже создает ApplicationContext, который должен загружать Controller'ы, ViewResolver'ы, MappingHandler'ы.
Бины из web tier видят бины уровня middle-tier, но не наоборот.
В простых случаях можно обойтись только контекстом из DispatcherServlet, но если есть что-то из нижеперечисленного, то не получится:
- несколько DispatcherServlet, которые разделяют сервисы
- legacy/non-Spring servlets, которым нужны бины
- есть сервлетные фильтры (Spring Security's DelegatingFilterProxy, OpenEntityManagerInViewFilter, ...)
TODO: Способы декларирования транзакций, когда можно проксировать классы, что будет при циклических зависимостях в контейнере.
P.S. Пара ссылок http://nikcode.blogspot.ru/2011/09/spring-2-rest-spring-web-mvc.html
http://www.devlogg.com/2011/08/spring-mvc.html
http://www.tutorialspoint.com/spring/spring_interview_questions.htm
P.S. Пара ссылок http://nikcode.blogspot.ru/2011/09/spring-2-rest-spring-web-mvc.html
http://www.devlogg.com/2011/08/spring-mvc.html
http://www.tutorialspoint.com/spring/spring_interview_questions.htm
Comments
Post a Comment