Введение в Spring Framework 2.5

Rod Johnson, “Introduction to the Spring Framework 2.5”, public translation into Russian from English More about this translation.

Translate into another language.

С тех пор как я последний раз обновлял эту статью в мае 2005 года, Spring фрэймворк продолжал набирать популярность, и стал стандартом де-факто для Enterprise Java разработки. Пока он развивался с версии 1.2 до теперешней версии 2.5, он был принят в еще более широком спектре отраслей и проектов. В этой статье я попытюсь объяснить, чего Spring собирается достичь, и как, я полагаю, это может помочь вам в разработке Enterprise Java приложений.

Почему Spring?

Я верю, что Sping уникален, по нескольким причинам:

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

* Spring - самодостаточный модульный фреймворк, с выраженной многослойной архитектурой. Вы можете использовать каждую из его частей независимо, и при этом его архитектура останется внутренне целостной. Вы получите максимум пользы на любом этапе изучения. Например, вы можете использовать Spring только для упрощения использования JDBC, а можете использовать его для управления бизнес объектами. Кроме того, можно достаточно легко внедрить Spring в существующие проекты.

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

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

* Spring Framework является ядром Spring Portfolio, быстро развивающегося комплексного решения для разработки корпоративных приложений на Java, которое демонстрирует такой-же последовательный подход к разработке, как и сам Spring Framework.

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

Будучи open-source проектом c февраля 2003, Spring имеет уже долгую историю. Этот проект основан на исходном коде к книге, Expert One-on-One J2EE Design and Development, вышедшей в конце 2002 года. Идеи, изложенные в книге, легли в основу видения архитектуры Spring. Впрочем, основные его архитектурные принципы относятся к началу 2000 года, и отражают мой опыт в создании инфраструктуры целой серии коммерчески успешных проектов.

У фреймворка почти 40 разработчиков, причем ведущие разработчики посвящают его разработке и поддержке все свое рабочее время в компании Interface21 (SpringSource). А расширяющееся open-source сообщество помогает развивать проект гораздо сильнее, чем это могли бы сделать отдельные разработчики внутри компании.

Архитектурные преимущества Spring

Перед тем, как коснуться специфики, давайте рассмотрим некоторые преимущества, которые Spring может дать вашему проекту:

* Spring может эффективно организовать ваши объекты среднего слоя. Spring делает ту "черную работу", которую пришлось бы делать вам, если бы вы использовали только Struts или другие j2ee-фрэймворки. А сервисы управления конфигурацией Spring'а могут быть использованы в любом слое архитектуры и в любой среде исполнения

* Spring может помочь устранить необходимость в использовании Singleton'ов во многих проектах. По моему опыту, это очень большая проблема, которая уменьшает тестируемость и объектную ориентированность.

* Spring устраняет необходимость использования собственных форматов файлов с описанием свойств, предлагая единый способ конфигурирования для всех приложений и проектов. Вам приходилось выяснять, что за странные имена свойств или системные свойства ищет данный класс (для чего вам нужно было смотреть javadoc или даже исходник)? Используя Spring, вы просто смотрите на свойства бина или аргументы конструктора. Использование принципов инверсии управления (IoC) и внедрения зависимостей (DI), обсуждаемых ниже, помогают добиться упрощения.

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

* Spring спроектирован таким образом, что приложения, созданные на его основе, настолько минимально зависят от его API, насколько это возможно. Большинство бизнес-объектов в Spring-приложениях вообще не имеют ссылок на Spring.

* Приложения, разработанные на базе Spring, очень легко тестировать. Для определенных сценариев модульного тестирования Spring Framework предоставляет mock-объекты и классы поддержки тестов. Spring также предоставляет уникальную функциональность поддержки интеграционных тестов в виде Spring TestContext Framework и классы, поддерживающие JUnit 3.8, что позволяет тестировать код быстро и просто, даже при работе с базой данных.

* Spring помогает решать проблемы, используя наиболее "легковесную" инфраструктуру. Он предоставляет подходящую для большинства приложений альтернативу компонентам EJB. Spring, например, может использовать АОП для реализации декларативного управления транзакциями без использования EJB-контейнера, и даже без реализации JTA (в том случае, если вам нужно работать с единственной базой данных или если вы хотите обойтись без двухфазной фиксации).

* Spring предоставляет целостный фреймворк по доступу к данным с использованием JDBC или O/R-средств, таких как TopLink, Hibernate, или реализации JPA или JDO.

* Spring предоставляет целостную и простую во многих областях приложения модель программирования, идеально подходящую в качестве архитектурного "клея". Вы можете видеть эту целостность в подходе Spring'а к интеграции с JDBC, JMS, JavaMail, JNDI и многими другими важными API.

По сути, Spring - технология, предназначенная для построения приложения с помощью обычных классов Java (POJO-объектов). То есть вы можете разрабатывать компоненты как POJO-объекты, содержащие только бизнес-логику, в то время как фреймворк берет на себя большую того, что вам нужно для построения j2ee-приложения, даже в тех областях, которые вы не предполагали затрагивать при первоначальном проектировании приложения. Эта цель требует сложного фреймворка, который скрыл бы эту сложность от разрабочика. Поскольку ваша бизнес-логика не затрагивает организации инфраструктуры, то можно наслаждаться жизнью. Бизнес-логика должна изменяться вместе с требованиями бизнеса. И влияние неизбежных изменений инфраструктуры (например, при смене сервера приложений) будет минимальным только если бизнес-логика абстрагирована от нее.

Таким образом Spring дает вам возможность внедрить самое простое и доступное решение ваших проблем, что многого стоит.

Что делает Spring?

Spring предоставляет широкую функциональность. Поэтому я поочередно расскажу о каждой области.

Цель

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

Spring не изобретает велосипед заново. Вы не найдёте ни новых пакетов журналирования, ни пулов соединения, ни координатора распределённых транзакций. Все эти возможности предоставляются как сторонними open-source проектами (например Commons Logging, который мы используем для журналирования, или Commons DBCP), так и вашим сервером приложений или веб-контейнером. По этой-же причине мы не предоставляем собственного средства ORM (объектно-реляционной отображения), для этого существуют готовые решения, например TopLink, Hibernate, JPA или JDO.

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

Внутренняя целостность Spring приносит свою пользу. Все разработчики поют одну песню, основные принципы которой остаются верными идеям описанным в книге "Expert One-on-One J2EE Design and Development". И мы можем использовать некоторые центральные концепции, такие как инверсия управления, во многих областях.

Приложение, основанное на Spring может быть легко перенесено на другой сервер приложений или веб-контейнер. (Функциональность классов ядра Spring не зависит от определенного контейнера). Конечно, достижение портируемости - это всегда сложная задача, но мы избегаем какой-либо платформной специфики или нестадартности с точки зрения разработчика и предоставляем возможность использования пользователям WebLogic, Tomcat, Resin, JBoss, Jetty, Geronimo, WebSphere и других серверов приложений. Не "агрессивный" [non-invasive] , основанный на использовании POJO подход позволяет использовать преимущества специфичных для среды возможностей не в ущерб портируемости системы, как в случае улучшенной функциональности управления транзакциями у серверов приложений WebLogic, WebSphere и контейнера OC4J, которая неявно использует проприетарный API компаний BEA и IBM.

IoC-контейнер

Ядро Spring - это пакет org.springframework.beans, созданный для работы с POJO. Этот пакет обычно не используется пользователями напрямую, но является фундаментом для многих классов, реализующих функциональность Spring.

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

Несколько слов о термине "бин": самые ранние версии Spring были предназначены только для конфигурирования Java бинов. Начиная с версии 1.0 Spring может конфигурировать любые Java объекты - безотносительно того, используют ли они методы-акцессоры или изменяющие [mutator] методы (и в версии 2.5 это еще более гибко). Тем не менее, термин "Spring-бин" остается общеупотребимым. Более точный термин - "объект, управляемый Spring'ом" - отражает тот факт, что Spring не только конфигурирует объекты, но и управляет ими в процессе работы приложения (например, для того чтобы применить enterprise-сервисы при каждом вызове данного объекта).

Фабрики бинов поддерживают три режима жизненного цикла объектов:

* Синглтон: в этом случае создается один разделяемый экземпляр объекта с определенным именем, который может быть получен из фабрики. Этот режим является режимом по умолчанию и наиболее часто используется. Он идеально подходит для объектов-сервисов без состояния.

* Прототип, или не-синглтон: в этом случае каждое получение объекта из фабрики будет приводить с созданию нового экземпляра объекта. Например, это может быть использовано для того, чтобы позволить каждому вызвавшему [объекту] иметь ссылку на выделенную для него копию объекта.

* Произвольные области видимости (scopes) объектов, которые, обычно, взаимодействуют с хранилищем, расположенным вне контейнера. Некоторые из них являются встроенными, как, например, request или session для Web-приложений. Другие, такие как кластерные кэши, поставляются с продуктами третих разработчиков. В случае если ни одна из имеющихся встроенных scope не подходит, новую scope создать очень легко путем реализовации простого интерфейса.

Так как контейнер Spring управляет отношениями между объектами, он может предоставлять дополнительные возможности, где это необходимо, посредством сервисов, таких как пул для управляемых POJO, или поддержки горячей подмены, когда контейнер на лету заменяет целевой объект совершенно прозрачно для вызывающих объектов, гарантируя при этом целостность ссылок и потокобезопасность. Одна из прелестей внедрения зависимостей (Dependency Injection) состоит в том, что все это происходит прозрачно, без какого-либо привлечения стороннего API.

Поскольку интерфейс org.springframework.beans.factory.BeanFactory достаточно прост, он может быть реализован множеством способов. Интерфейс org.springframework.beans.factory.support.BeanDefinitionReader отделяет формат метаданных от реализаций, поэтому общие [generic] реализации интерфейса BeanFactory, предоставляемые Spring'ом, могут быть использованы с различными типами метаданных. Вы можете просто реализовать собственную фабрику бинов (BeanFactory) или BeanDefinitionReader, хотя большинству вользователей в этом нет необходимости. Наиболее часто используемые определения фабрики бинов следующие:

* XmlBeanFactory. Парсит простую, интуитивную XML структуру, определяющую класс и свойства именованного обьекта.

* DefaultListableBeanFactory: предоставляет возможность считывать описания бинов из файлов свойств, и создавать фабрики бинов программно.

Каждое определение бина может быть либо POJO-объектом (заданным именем класса, проинициализированными свойствами бина и аргументами конструктора), либо factory-бином. Интерфейс FactoryBean добавляет уровень абстракции [indirection]. Обычно он используется для создания объектов-прокси (заменителей) с использование AOP или других подходов: например, заменителей, которые добавляют декларативное упраление транзакциями. Это концептуально похоже на перехват EJB, но реализовано намного проще в использовании и дает больше возможностей.

Фабрики бинов могут образовывать иерархическую структуру, в которой дочерние фабрики "наследуют" определения своих предков. Это позволяет использовать общую конфигурацию во всем проекте, в то время как некоторые ресурсы, такие как контроллеры сервлетов, могут иметь свои собственные наборы объектов.

Эта мотивация для использования JavaBeans описана в части 4 Expert One-on-One J2EE Design and Development, которая доступна на сайте ServerSide (http://www.theserverside.com/) как бесплатный PDF.

Благодаря концепции фабрики бинов, Spring является IoC контейнером. (Мне не очень нравится термин 'контейнер', поскольку он вызывает ассоциацию с понятием тяжеловесного контейнера, такого как EJB контейнер. Фабрика бинов Spring - это контейнер, который может быть создан в одной строке кода и не требует специальных шагов по развертыванию.) Spring более всего ассоциируется с понятием инверсии управления (Inversion of Control), внедрением зависимостей (Depenedency Injection) - терминами, введенными Мартином Фаулером, Родом Джонсоном и группой программистов PicoContainer в 2003 г.

Принцип работы Инверсии управления (IoC) часто можно выразить в общеизвестном выражении Голливуда - "Не звоните мне, я сам вам позвоню". IoC перекладывает заботу о выполнении кода на платформу, вместо того чтобы им занимался сам код приложения. И где раньше ваш код обращался к какой-то библиотеке классов, там теперь IoC, напротив, вызывает ваш код. Обратные вызовы во множестве API, например setSessionContext() в сессионных EJB, показывает работу этой концепции.

Внесение зависимостей - это форма IoC, при которой удаляются явные зависимости от API контейнера. Для внесения в объекты приложения зависимостей, таких как ссылки на объекты помощников или конфигурационные значения, используются обычные Java-методы. И если в традиционных архитектурах контейнера, таких как EJB, комронент может спросить контейнер "где находится нужный мне объект X ?", то с использованием принципа внесения зависимостей уже сам контейнер обнаруживает, что компоненту нужен объект Х, и предоставляет ссылку на него во время исполнения. Причем нужный объект предоставляется контейнером на основе анализа сигнатуры метода (это относится к свойствам и конструкторам бинов) и, возможно, в соответствии с конфигурационными данными, указанными в XML-файле.

Два основных вида DI - это Setter Injection (внесение зависимостей с помощью setter-методов бина) и Constructor Injection (с помощью аргументов конструктора бина). Spring предоставляет полную поддержку обоих подходов и даже позволяет вам применять сразу оба вида DI для конфигурирования одного и того же объекта.

Кроме поддержки всех форм DI, Spring также предоставляет набор событий обратного вызова, а также API для обычного поиска [зависимостей] там, где необходимо. Однако мы рекомендуем использовать исключительно DI-подход.

Внедрение зависимостей имеет несколько важных особенностей. Например:

* Так как компонентам нет нужды искать используемые объекты во время выполнения приложения, их гораздо проще писать и поддерживать. В Spring-версии IoC компоненты объявляют свою зависимость от других компонентов через сеттеры или параметры конструктора. К примеру, нет нужды для поиска объектов с помощью JNDI, которая требует от разработчика написания кода, зависящего от среды выполнения.

* По тем же самым причинам гораздо проще тестировать код приложения. Например, свойства JavaBean'а просты, это чистая Java и их просто тестировать: просто напишите самодостаточный JUnit- или TestNG-метод, который создает объект и устанавливает соответствующие свойства.

* Хорошая реализация IoC должна сохранять строгую типизацию. Если вам нужна обобщенная фабрика для получения объектов-сотрудников (collaborators), вам придется привести результаты к требуемому типу. Это не большая проблема, но это некрасиво. С применением инверсии управления вы описываете строго типизированные зависимости в вашем коде, и теперь уже фреймворк отвечает за приведение типов. Это означает, что возможные несоответствия типов будут выявлены уже во время конфигурирования приложения фреймворком, и вам уже не нужно беспокоиться об обработке этих ошибки в своем коде.

* Зависимости становятся явными. Например, если класс пытается при своем создании загрузить файл свойств или соединиться с базой данных, предположения о среде выполнения могут быть не очевидными без чтения кода (что усложняет тестирование и уменьшает гибкость при развертывании приложения). С применением DI, зависимости становятся явными, и доступными в конструкторе или свойствах бина.

* Большинство бизнес-объектов не зависит от API IoC-контейнера, что упрощает их использование в наследуемом коде как совместно так и отдельно от IoC-контейнера. Например, программисты Spring часто задают конфигурацию Jakarta Commons DBCP DataSource как Spring бин: нет необходимости писать специального кода, чтобы сделать это. Мы утверждаем, что IoС-контейнер не является навязчивым: используя его, вы не нарушите свой код зависимостью от его API. Едва ли не каждый POJO-объект может быть использован как компонент в фабрике Spring бинов. Имеющиеся JavaBeans или объекты с различными конструкторами работают очень хорошо. Также в Spring существует уникальная поддержка создания экземпляров объектов с помощью статических фабричных методов или обыкновенных методов в других объектах, управляемых IoC-контейнером.

Стоит выделить последний пункт. Шаблон Dependency Injection не похож на традиционные контейнерные архитектурные технологии, такие как EJB, минимизацией зависимости кода приложения от контейнера. Это означает, что ваши бизнес-объекты потенциально могут быть запущены в различных Dependency Injection фреймворках (или без использования фреймворка) без изменения кода.

Мой опыт и опыт программистов Spring подсказывает: трудно переоценить пользу от использования IoC и, в особенности, Dependency Injection, которую они приносят коду приложения.

Spring BeanFactories очень легковесные. Пользователи успешно используют их как в апплетах, так и в Swing приложениях. Нет специальных шагов по развёртыванию приложения и нет затрат на время для загрузки контейнера (хотя определённые объекты которые настраиваются контейнером, конечно же, могут потребовать некоторое время для инициализации). Эта способность инстанциировать контейнер почти мгновенно в любой области приложения может оказаться очень ценной.

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

Что наиболее значимо для разработчиков приложений - так это то, что при любом количестве BeanFactories, все они предоставляют собой хорошо описанный слой бизнес объектов. Все это аналогично слою локальных сессионных бинов, но такое решение является несколько более упрощенным вариантом (но не менее мощным). А для создания хорошей архитектуры, очень важно иметь хорошо описанный слой бизнес объектов.

Спринговский ApplicationContext - это часть интерфейса BeanFactory, которая поддерживает:

* Поиск сообщений с поддержкой интернационализации

* Механизм событий, позволяющий объектам приложения публиковать события, а также регистрироваться на получение уведомлений о них

* Автоматическое распознавание специальных универсальных определений бинов, которые настраивают поведение контейнера

* Переносимые настройки доступа к файлам и ресурсам

Пример XmlBeanFactory

Пользователи Spring традиционно конфигурируют свои приложения в XML-файлах "определения бинов", однако, существуют и другие способы, такие как аннотации исходного кода, properties-файлы, Java код. При использовании различных способов конфигурации Spring будет объединять результаты конфигурирования от различных источников.

Корень документа описания Spring XML бина - элемент. Этот элемент содержит одно или более описаний бинов. Чаще всего необходимо указать класс и задать свойства каждого такого бина. Так же необходимо указать id, являющийся именем бина, который мы будем указывать в нашем коде.

Давайте посмотрим на простой пример, в котором конфигурируются три объекта приложения со связями, часто встречающимися в j2ee-приложениях:

* DataSource используется для соединения с реляционной базой данных.

* Объект доступа к данными (DAO), который использует DataSource.

* Бизнес-объект, который использует DAO в процессе работы.

В следующем примере, мы будем использовать класс BasicDataSource из проекта Jakarta Commons DBCP. Класс ComboPooledDataSource из проекта C3PO также является хорошим выбором. BasicDataSource, как и множество других классов, может быть легко использован в Spring Bean Factory, так как он предоставляет возможности по Java-Bean конфигурации. Метод close() [объекта dataSource], который должен быть вызван при завершении работы [объекта Bean Factory], может быть указан в атрибуте "destroy-method" (атрибуте описания бина dataSource). Это сделано для того,чтобы избежать для класса BasicDataSource необходимости реализовывать какой-либо Spring'овый интерфейс.

<beans>

<bean id="myDataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="com.mysql.jdbc.Driver"
p:url="jdbc:mysql://localhost:3306/mydb"
p:username="someone"/>

Все свойства BasicDataSource, которые нам нужны, - строки, так что мы можем указать их, используя префикс "p:" специального невалидируемого пространства имен, который позволяет устанавливать свойства бинов в виде XML-атрибутов. Такое сокращение было предложено в Spring 2.0 как удобная альтернатива аттрибуту или подэлементу "value", используемому для установки значений, проблематичных для задания в виде XML-атрибутов. Для конвертирования строковых представлений в другие типы, если это необходимо, Spring использует стандартный механизм JavaBeans PropertyEditor .

Таким образом мы определили DAO, содержащий в бине ссылку на DataSource. Отношения между бинами - специфическое использование комбинации префикса "p:" и суффикса "ref-", атрибута "ref" или элемента:

<bean id="exampleDataAccessObject"
class="example.ExampleDataAccessObject"
p:dataSource-ref="myDataSource"/>

Бизнес-объект ссылается на DAO и на свойство типа int (exampleParam)

<bean id="exampleBusinessObject" class="example.ExampleBusinessObject"
p:dataAccessObject-ref="exampleDataAccessObject"
p:exampleParam="10"/>
</beans>

Взаимосвязи между объектами чаще всего задаются явным образом в конфигурации, так, как это было сделано в примере. Этот подход приемлем в большинстве случаев. Однако, Spring так же поддерживает два механизма автоматического связывания ("autowire") - это когда зависимости между бинами находятся автоматически: автоматическое связывание по типу и по имени.

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

Это ограничение автоматического связывания по типу, часто может быть преодолено автоматическим связыванием по имени. При использовании этого типа автосвязывания, вместо типов используются имена. К примеру, если бин выражает зависимость, определяя метод setMaster, Spring попытается найти бин с именем "master" в BeanFactory и "внедрить" этот бин для установления зависимости. В то время как автосвязывание по типу работает либо с конструкторами и set-методами, автосвязывание по имени автоматически работает только с set-методами: это результат того факта, что Java reflection не предоставляет доступ к именам параметров конструкторов или других методов. Spring 2.5 предоставляет возможность использования автосвязывания по имени в конструкторах "описывая" параметры аннотацией @Qualifier. Для дальнейшего изучения данного вопроса смотрите раздел "Вне XML".

Мы можем использовать автосвязывание по типу так же, как это сделано в следующем примере, в том случае, если мы не хотим задавать эти связи явным образом:

Таким образом Spring автоматически задаст свойство dataSource бина exampleBusinessObject реализацией той интерфейса DataSource, которая будет в списке бинов текущего BeanFactory. При это он выдаст ошибку если не будет ни одного, или, наоборот, будет несколько реализаций требуемого типа в текущем BeanFactory. Но мы все еще должны сами задать свойство exampleParam, т.к. это не ссылка.

Автоматическое связывание дает большой выигрыш в объеме настроек, особенно при использовании опций корневого элемента конфигурации, который может включить автоматическое связывание для всего контекста Spring. Это означает что контейнер проверяет структуру приложения с помощью рефлексии, и если вы, к примеру, добавите еще один аргумент к конструктору бина, Spring сможет использовать его без дополнительной настройки. Тем не менее, используя автоматическое связывание, следует аккуратно оценивать его плюсы и минусы .

Вынесение зависимостей из java кода часто дает большие преимущества по сравнению с прямым указанием связей в коде, т.к. всегда можно изменить XML не меняя не единой строчки java кода. К примеру, мы можем изменить бин myDataSource чтобы он указывал на другой класс использующий альтернативный пул соединений, или на тестовый источник данных. Мы можем использовать JNDI для того чтобы брать источник данных из сервера приложений используя другую настройку XML. И это не повлечет изменение java кода или настроек других бинов.

Теперь давайте рассмотрим пример бизнес-объекта. Заметьте, что зависимостей от Spring в коде нет. Spring IoC контейнер не агрессивный, объекту приложения обычно не нужно о нем знать.

public class ExampleBusinessObject implements MyBusinessObject {

private ExampleDataAccessObject dao;

private int exampleParam;

public void setDataAccessObject(ExampleDataAccessObject dao) {

this.dao = dao;

}

public void setExampleParam(int exampleParam) {

this.exampleParam = exampleParam;

Pages: ← previous Ctrl next
1 2 3 4 5 6

© Rod Johnson

Original (English): Introduction to the Spring Framework 2.5

Translation: © Юрий, Igor Artamonov, Nuke, batoha83, And, Виктор Колодревский, flamey, Егор Маркин, SoftIce, Kolun4ek, dj-begemot, anklav, akorobejnikov, Hazanko, house_san, Kodeks, darkstar, serger, Михаил, maratische, broundee, meowth, Руслан Гроховецкий, kozkozkoz, C-est_la_vie, EgorSK, zheka82, keith, YuM, artobstrel95, Viktor.Krasikov, daring, eugene-kalitsko, ramanchik, andreybig .

License: Public

translated.by crowd

Like this translation? Share it or bookmark!