КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Введение. Что такое Контейнер объектов и зачем он нужен
Основы SpringFramework Лекция посвящена основам популярного IoC/Dependency Injection (http://martinfowler.com/articles/injection.html) контейнера объектов SpringFramework с примерами на Java. Несмотря на то, что в качестве целевой платформы выбрана Java, принципы и практики, и даже многие приёмы конфигурирования и работы с объектами и классами, описанные в лекции полностью, либо с незначительными модификациями применимы и к платформе.Net и соответвующему проекту SpringFramework.Net.
Под контейнером объектов в рамках лекции будем подразумевать некоторый компонент, реализующий шаблон ООП типа Assembler (или сборщик объектов). Иными словами, контейнер объектов отвечает за создание экземпляров объектов, поиск нужных экземпляров объектов, и связь этих экземпляров друг с другом, согласно модели структурных связей (создание и инициализация коллабораторов). Т.е. фактически контейнер объектов отвечает за создание и управление жизненным циклом графа объектов системы.
В ООП важным моментом при проектировании классов и систем состоящих из них является проектирование классов как можно более независимыми друг от друга (low-coupling). Положительным следствием такого принципа является относительная лёгкость взаимозамены одной реализации класса другой, при условии что оба класса реализуют общий интерфейс. Этим же продиктована и рекомендация проектирования классов и их взаимодействий на основании интерфейсов. Т.е. при разработке рекомендуется избегать прямого обращения к конкретной реализации класса и использовать вместо этого общий интерфейс. Например при использовании коллекций в Java, вместо конкретных реализаций рекомендуется использовать интерфейсы, так вместо прямого обращения к ArrayList рекомендуется использовать интерфейс List или ещё лучше – интерфейс Collection. Это позволит развязать зависимые реализации классов и подставить при необходимости, например вместо ArrayList LinkedList.
Напомними основные обпределение IoC/DI:
Collaborator – объект или компонент, участвующий в структурных связях и взаимодействиях с целевым объектом (под целевым объектом в данном контексте понимается рассматриваемый класс или объект). Dependency Injection – техника внедрения объектов Collaborator’ов в целевые объекты извне, т.е. при помощи дополнительных классов, выступающих в роли Assembler’ов.
Dependency Injection позволяет избавиться от необходимости жёстко кодировать реализацию конкретного интерфейса непосредственно в целевом классе.
SpringFramework состоит из набора функциональный групп организованных в примерно 20 модулей. Модули сгруппированы в:
Интерфейс org.springframework.context.ApplicationContext представляет для программиста IoC контейнер и отвечает за создание, конфигурирование и сборку графов объектов, которые используются в приложениях. Контейнер получает инструкции о том какие объекты и в каких связях создавать с помощью конфигурационных механизмов. Конфигурация может быть представлена тремя способами
SpringFramework поставляется сразу с несколькими уже готовыми реализациями интерфейса ApplicationContext:. ClassPathXmlApplicationContext FileSystemXmlApplicationContext. Первый предназначен для загрузки конфигурации контекста (графа объектов) из classpath, второй для загрузки из файловой системы.
В большинстве случаев от программиста не требуется написание какого либо кода для того чтобы инициализировать контекст. Например, работая с web-приложением, программист может воспользоваться специальным фильтром или сревлетом, входящим в комплект поставки SpringFramework, для того, что бы инициализировать контекст их XML файла. Для этого необходимо в конфигурационном файле web.xml указать:
При этом файл с конфигурацией контекста следует положить в /WEB-INF/applicationContext.xml
Тем не менее, если речь идёт о простом консольном приложении, работающем внеконтекста (например Web-контейнера), то программисту, для инициализации контекста и получения доступа к нему необходимо в программе сделать следующее:
При этом, если файлов с описанием конфигурации контекста больше одного, они могут быть перечислены через запятую. В данном примере, так как используется ClassPathXmlApplicationContext, то искомые файлы будут загружаться с помощью механизма class loader’а. Т.е. по сути должны быть доступны в classpath.
XML файл конфигурации контекста имеет определённую структуру:
Id задаёт идентификатор бина в контексте, а class – задаёт полное имя Java класса, который используется для создания бина.
В процессе работы над приложением, при увеличении его размера, размер XML файла может увеличиваться до размеров неудобных для работы. SpringFramework позволяет разделять конфигурацию контекста на несколько файлов. Это так же бывает полезно при логическом разделении конфигурации контекста (например разные файлы для разных подсистем или архитектурных слоёв – один для сервисов, другой для DAL и т.п.):
Для этого используется элемент <import>. При этом в качестве имени импортируемого файла с контекстом принимается либо абсолютное (если имя начинается с “/”), либо относительное. Абсолютность или относительность сопоставляются в зависимости от типа контекста: если это файловый контекст – то речь идёт о файлах, а если о classpath, то о ресурсах доступных через механизм classloader.
Чтобы создать контекст из файла конфигурации находящимся в classpath можно использовать конструкцию:
Далее, для получение экземпляра бина из контекста по имени можно использовать метод getObject():
При этом весь код Main-класса будет выглядеть следующим образом:
Для начала надо создать класс, на основе которого будет создаваться бин:
Далее необходимо создать XML файл с конфигурацией контекста:
Важно отметить, что элементы <propperty> позволяют задавать значения в экземпляре класса. Это даёт возможность гибко конфигурировать экземпляры классов в конкретном контексте. Важно так же заметить, что для успешного задания полей класса, класс должен корректно, в соответвии с договорённостями об именовании методов и полей, правильно задать методы set и get для полей/свойств класса. Эти договорённости описаны в спецификации Java Beans Specification. Коротко, они задают именования полей класса должны начинаться с маленькой буквы, camelStyle, а имена методов доступа к полям должны префиксоваться get-, set-, is-. Т.е. если поле называется myField, то методы должны называться соответвенно setMyField(), getMyField(). В том случае, если поле имеет тип Boolean, то допускается вместо названия метода get- префиксовать is-, например isMyField(). В таком случае, SpringFramework, используя механизм reflection устанавливает поля в заданные значения. Интересным и удобным является то, что, неспотря на строковое представление значений, подставляемых в поля класса в XML файле конфигурации контекста, если тип поля не строка, а например int, то происходит автоматическая конвертация. Т.е. поле initial, в примере будет правильно инициализировано числовым значением. Это так же даостигается с использованием механихма reflection. Spring определяет тип, который ожидает метод set- и пытается привести строковое представление значения в файле к этому типу. Для этого Spring использует механизм PropertyEditor’ов или конвертеров. Для каждого типа можно зарегистрировать свой конвертер. Вышеприведённый пример можно сократить, используя более компактную нотацию XML файла конфигурации:
Более того, начиная с версии 2.0, когда в Spring стали доступны механизмы расширения синтаксиса путём подключения дополнительных схем, стал доступен ещё более краткий способ:
Всё тоже самое доступно и с помощью задания свойств через параметры конструктора:
Таким образом мы видим, что SpringFramework достигает одной из основных целей: non-intrusive approach, т.е. подход с минмальным вмешательством в структуру кода. Т.е. если класс уже создан и у него есть конструктор с параметрами, Spring позволяет его использовать вполне естественно. Если класс использует поля с типами отличными от строк, Spring автоматически производит конвертацию, не вынуждая перепроектировать класс. Для того чтобы стать бином, класс не должен быть каким либо специальным образом модифицирован.
Дата добавления: 2014-01-05; Просмотров: 806; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |