|
|
(не показано 87 промежуточных версий этого же участника) |
Строка 1: |
Строка 1: |
| == Жизненный цикл Spring Bean ==
| |
| [[Файл:SpringBeanLifeCycle.png|безрамки|800x800пкс]]
| |
| === InitializingBean ===
| |
| Вызывается метод afterPropertiesSet(), который служит той же цели, что и метод init()
| |
| === @PostConstruct ===
| |
| Начиная с версии Spring 2.5, поддерживаются также и аннотации JSR-250 для указания метода,
| |
| который платформа Spring должна вызвать, если соответствующая аннотация,
| |
| связанная с жизненным циклом бина, существует в классе.
| |
| Это тот же init-method, только имя метода может быть любым.
| |
| Для работы необходимо добавить дескриптор context:annotation-config.
| |
|
| |
| === DisposableBean ===
| |
| Вызывается метод destroy(), который служит той же цели, что и метод указываемый в атрибуте destroy-metod.
| |
|
| |
| === @PreDestroy ===
| |
| Применение аннотации жизненного цикла @PreDestroy, определенной в стандарте JSR-250,
| |
| которая является противоположностью @PostConstruct.
| |
| Для работы необходимо добавить дескриптор context:annotation-config.
| |
|
| |
| = Конфигурация XML = | | = Конфигурация XML = |
| == beans ==
| |
| === beans default-lazy-init ===
| |
| Атрибут инструктирует Spring о том, что экземпляры бинов, определенных в конфигурационном файле,
| |
| должны создаваться только при их запросе приложением.
| |
| <nowiki> <beans ... default-lazy-init = "true">
| |
| <bean ... />
| |
| ...
| |
| </beans></nowiki>
| |
|
| |
| == beans profile ==
| |
| Профиль заставляет Spring конфигурировать только тот контекст ApplicationContext, который определен, когда указанный профиль становится активным.
| |
| Активируется опцией -Dspring.profiles.active=activeProfile
| |
| Пример профиля:
| |
| <nowiki> <beans xmlns = "http://www.springframework.org/schema/beans"
| |
| xmlns:xsi = "http://www.wЗ.org/2001/XМLSchema-instance"
| |
| xsi:schemaLocation = "http://www.springframework.org/schema/beans
| |
| http://www.springframework.org/schema/beans/spring-beans.xsd"
| |
| profile = "profile1">
| |
| ...
| |
| </beans></nowiki>
| |
| см. Environment
| |
| == context:component-scan == | | == context:component-scan == |
| Дескриптор <context:component-scan> сообщает Spring о необходимости | | Дескриптор <context:component-scan> сообщает Spring о необходимости |
Строка 51: |
Строка 11: |
| Также можно указать пакет для сканирования через установку атрибута base-package. | | Также можно указать пакет для сканирования через установку атрибута base-package. |
| Еще можно указать исключения через context:exclude-filter. | | Еще можно указать исключения через context:exclude-filter. |
|
| |
| == context:property-placeholder ==
| |
| Дескриптор context:property-placeholder для загрузки свойств в Sрring-интерфейс Environment, который помещен в оболочку интерфейса ApplicationContext. Кроме того, мы применяем заполнители для внедрения значений в бин AppProperty.
| |
| <nowiki> <context:property-placeholder location="classpath:application.properties"/>
| |
| <bean id="appProperty" class="AppProperty">
| |
| <property name="applicationHome" value="${application.home}"/>
| |
| <property name="userHome" value="${user.home}"></property>
| |
| </bean></nowiki>
| |
|
| |
|
| == bean == | | == bean == |
Строка 85: |
Строка 37: |
| Пример: | | Пример: |
| <nowiki><property name="map"> | | <nowiki><property name="map"> |
| <map>
| | <map> |
| <entry key="v1">
| | <entry key="v1"> |
| <value>Hello World!</value>
| | <value>Hello World!</value> |
| </entry>
| | </entry> |
| <entry key="refToBean">
| | <entry key="refToBean"> |
| <ref local="localBeanId"/>
| | <ref local="localBeanId"/> |
| </entry>
| | </entry> |
| </map>
| | </map> |
| </property></nowiki>
| | </property></nowiki> |
|
| |
|
| ==== bean/property/set ==== | | ==== bean/property/set ==== |
|
| |
|
| <nowiki><property name="set"> | | <nowiki><property name="set"> |
| <set>
| | <set> |
| <value>Hello World 1 </value>
| | <value>Hello World 1 </value> |
| <ref local="oracle" />
| | <ref local="oracle" /> |
| </set>
| | </set> |
| </property></nowiki>
| | </property></nowiki> |
|
| |
|
| ==== bean/property/list ==== | | ==== bean/property/list ==== |
|
| |
|
| <nowiki><property name="list"> | | <nowiki><property name="list"> |
| <list>
| | <list> |
| <value>Hello World!</value>
| | <value>Hello World!</value> |
| <ref local="localBeanId"/>
| | <ref local="localBeanId"/> |
| </list>
| | </list> |
| </property></nowiki>
| | </property></nowiki> |
|
| |
|
| ==== bean/property/props ====
| | === bean/property/props === |
| Дескриптор <props> позволяет передавать в качестве значений только String, | | Дескриптор <props> позволяет передавать в качестве значений только String, |
| потому что класс Properties разрешает только значения свойств типа String. | | потому что класс Properties разрешает только значения свойств типа String. |
Строка 139: |
Строка 91: |
| Пример Method Injection: | | Пример Method Injection: |
| <nowiki> <bean id="abstractLookupBean" class="com.a.AЬstractLookupDemoBean"> | | <nowiki> <bean id="abstractLookupBean" class="com.a.AЬstractLookupDemoBean"> |
| <lookup-method name="getMyHelper" bean="helper"/>
| | <lookup-method name="getMyHelper" bean="helper"/> |
| </bean></nowiki>
| | </bean></nowiki> |
| | |
| === bean/replaced-method ===
| |
| <nowiki> <bean id="replacementTarget" class="com.a.ReplacementTarget"> | |
| <replaced-method name="formatMessage" replacer="methodReplacer">
| |
| <arg-type>String</arg-type>
| |
| </replaced-method>
| |
| </bean></nowiki>
| |
| === bean name-алиасы ===
| |
| Через name:
| |
| <nowiki><bean id="name1" name="name2 name3,name4;name5" class="java.lang.String"/></nowiki>
| |
| Через alias:
| |
| <nowiki><alias name = "namel" alias = "name6"/></nowiki>
| |
|
| |
|
| Извлечь список псевдонимов бина можно с помощью вызова метода ApplicationContext.getAliases(String) с передачей ему любого из имен бина или его идентификатора. Этот метод возвращает в виде массива String список псевдонимов, содержащий все псевдонимы кроме указанного при вызове.
| | = util = |
| | |
| === bean scope ===
| |
| По умолчанию Spring устанавливает атрибут scope в singleton (одиночный).
| |
| Область действия на уровне prototype (прототип) заставляет Spring создавать новый экземпляр бина каждый раз, когда он запрашивается приложением.
| |
| Пример:
| |
| <nowiki><bean id="nonSingleton" class="java.lang.String" scope="prototype" c:_0="Sasha V."/></nowiki>
| |
| | |
| === bean depends-on ===
| |
| В следующей конфигурации мы утверждаем, что бин по имени beanA зависит от бина
| |
| под названием beanB.
| |
| <nowiki> <bean id="beanA" class="BeanA" depends-on="beanB"/>
| |
| <bean id="beanB" class="BeanB"/></nowiki>
| |
| Во время разработки приложений такого подхода лучше избегать; вместо этого определяйте зависимости с помощью контрактов Setter Injection и Constructor Injection.
| |
| | |
| === bean autowire ===
| |
| В атрибуте autowire для бина понадобится указать используемый режим автосвязывания.
| |
| Платформа Spring поддерживает следующие режимы автосвязывания: byName, ЬуТуре, constructor, default и no (автосвязывание отключено; устанавливается по умолчанию).
| |
| | |
| === bean lazy-init ===
| |
| Атрибут lazy-init устанавливается в true, чтобы информировать Spring о необходимости создания экземпляра бина только при первом его запросе, а не во время начальной загрузки.
| |
| | |
| === bean parent ===
| |
| Наследование бинов:
| |
| <nowiki> <bean id="inheritParent" class="SimpleBean" p:name="Name1" p:age="32"/>
| |
| <bean id="inheritChild" class="SimpleBean" parent="inheritParent" р:аgе="ЗЗ"/></nowiki>
| |
| | |
| === bean abstract ===
| |
| В случае если определение родительского бина не должно быть доступным для поиска из ApplicationContext,
| |
| к дескриптору bean, объявляющему родительский бин, можно добавить атрибут abstract="true".
| |
| | |
| === bean init-method ===
| |
| Атрибут init-method, который сообщает платформе Spring, что она должна вызвать метод init(),
| |
| как только завершит конфигурирование бина.
| |
| <nowiki><bean id="iBean" class="BeanClass" init-method="init"/></nowiki>
| |
| Аналоги: InitializingBean.afterPropertiesSet(), @PostConstruct
| |
| | |
| === bean destroy-method ===
| |
| Чтобы назначить метод для вызова во время уничтожения бина, нужно просто указать имя этого метода в атрибуте destroy-method дескриптора <bean> для бина.
| |
| Платформа Spring вызывает этот метод непосредственно перед уничтожением одиночного экземпляра бина (она не будет вызывать этот метод для бинов с областью действия на уровне прототипа).
| |
| <nowiki><bean id="dBean" class="BeanClass" destroy-method="destroy"/></nowiki>
| |
| Аналоги: DisposableBean.destroy(), @PreDestroy
| |
| | |
| === bean factory-bean ===
| |
| Иногда нужно создавать экземпляры компонентов JavaBean, которые были предоставлены приложением третьей стороны, не поддерживающим Spring.
| |
| Вы не знаете, как создавать экземпляр этого класса, но вам известно, что приложение третьей стороны предлагает класс, который можно использовать для получения экземпляра JavaBean, необходимого вашему приложению Spring.
| |
| <bean id="defaultDigest"
| |
| factory-bean="defaultDigestFactory"
| |
| factory-method="createinstance"/>
| |
| | |
| == util ==
| |
| Пространство имен util, предоставляемое Spring, для объявления бинов, хранящих свойства коллекций. | | Пространство имен util, предоставляемое Spring, для объявления бинов, хранящих свойства коллекций. |
| === util:map ===
| | == util:map == |
| <nowiki> <util:map id="map" map-class = "java.util.HashMap"> | | <nowiki> <util:map id="map" map-class = "java.util.HashMap"> |
| <entry key = "someValue">
| | <entry key = "someValue"> |
| <value>Hello World!</value>
| | <value>Hello World!</value> |
| </entry>
| | </entry> |
| <entry key="someBean">
| | <entry key="someBean"> |
| <ref bean="beanId"/>
| | <ref bean="beanId"/> |
| </entry>
| | </entry> |
| </util:map></nowiki>
| | </util:map></nowiki> |
|
| |
|
| === util:properties ===
| | == util:properties == |
| <nowiki> <util:properties id="props"> | | <nowiki> <util:properties id="props"> |
| <prop key="firstName">Sasha</prop>
| | <prop key="firstName">Sasha</prop> |
| <prop key = "secondName">V.</prop>
| | <prop key = "secondName">V.</prop> |
| </util:properties></nowiki>
| | </util:properties></nowiki> |
|
| |
|
| === util:set ===
| | == util:set == |
| <nowiki> <util: set id="set"> | | <nowiki> <util: set id="set"> |
| <value>Hello World!</value>
| | <value>Hello World!</value> |
| <ref bean = "oracle"/>
| | <ref bean = "oracle"/> |
| </util: set></nowiki>
| | </util: set></nowiki> |
|
| |
|
| === util:list ===
| | == util:list == |
| <nowiki> <util:list id="list"> | | <nowiki> <util:list id="list"> |
| <value>Hello World!</value>
| | <value>Hello World!</value> |
| <ref bean="oracle"/>
| | <ref bean="oracle"/> |
| </util:list></nowiki>
| | </util:list></nowiki> |
|
| |
|
| = Кофигурация аннотациями = | | = Кофигурация аннотациями = |
Строка 269: |
Строка 159: |
| @Component("injectSimpleConfig") | | @Component("injectSimpleConfig") |
| @Service является специализацией @Component, отражающей тот факт, что аннотированный класс предоставляет бизнес-службу другим уровням внутри приложения. | | @Service является специализацией @Component, отражающей тот факт, что аннотированный класс предоставляет бизнес-службу другим уровням внутри приложения. |
|
| |
| == @Configuration ==
| |
| Аннотация @Configuration для информирования платформы Spring о том, что это конфигурационный файл, основанный на Java.
| |
|
| |
| После этого для объявления бина Spring и требований DI применяется аннотация @Bean.
| |
|
| |
| == @Bean ==
| |
| Аннотация @Bean эквивалентна дескриптору <bean>, а имя метода - атрибуту id дескриптора <bean>.
| |
|
| |
| == Другие аннотации ==
| |
| @ImportResource(value = "classpath:META-INF/spring/app-context-xml.xml") - для импортирования конфигурации из ХМL-файлов, что означает возможность совместного применения ХМL и Jаvа-классов конфигурации, хотя поступать подобным образом не рекомендуется.
| |
|
| |
| @PropertySource(value = "classpath:message.properties") применяется для загрузки файлов свойств в ApplicationContext и принимает в качестве арrумента местоположение (допускается указывать более одного местоположения). В ХМL той же самой цели служит дескриптор <context:property-placeholder>.
| |
|
| |
| @ComponentScan(basePackages = {"com.test"})
| |
|
| |
| @EnableTransactionManagement
| |
|
| |
| @Lazy(value = true)
| |
|
| |
| @DependsOn(value = "messageProvider")
| |
|
| |
| @Qualifier
| |
|
| |
| === JSR-330 ===
| |
| @Named("messageProvider") - применяется для объявления внедряемого бина (аналогично аннотации @Component или @Service в Spring).
| |
|
| |
| @Inject
| |
|
| |
| @Singleton - стандарте JSR-330 по умолчанию бин является неодиночным, что похоже на область действия на уровне прототипа в Spring. Таким образом, если вы хотите, чтобы в среде JSR-330 ваш бин был одиночным, то должны применять аннотацию @Singleton.
| |
|
| |
| = Классы Spring = | | = Классы Spring = |
| == ProtertyEditor ==
| |
| ByteArrayPropertyEditor - String в массив байтов
| |
|
| |
| ClassEditor - полностью определенное имя класса в экземпляр Class
| |
|
| |
| CustomВooleanEditor - в Jаvа-тип Boolean
| |
|
| |
| CustomCollectionEditor - в целевой тип Collection
| |
|
| |
| ''CustomDateEditor'' - в значение java.util.Date. '''Этот редактор с желаемым форматом даты необходимо зарегистрировать в ApplicationContext.'''
| |
|
| |
| CustomNumberEditor - в числовое значение, которым может быть Integer, Long, Float или Double
| |
|
| |
| FileEditor - в экземпляр File
| |
|
| |
| InputStreamEditor - строковое представление ресурса (например, файлового ресурса вида file: D: /temp/test. txt или classpath:test. txt) в свойство входного потока
| |
|
| |
| LocaleEditor - строковое представление локали, такое как en-GB, в экземпляр java.util.Locale
| |
|
| |
| Pattern - в JDК-объект Pattern или наоборот
| |
|
| |
| PropertiesEditor - строку в формате ключl=значениеl ключ2=значение2 ключn=значениеn в экземпляр java.util.Properties с настройкой соответствующих свойств
| |
|
| |
| ''StringTrimmerEditor'' - усечение строковых значений перед внедрением. '''Этот редактор свойств должен быть явно зарегистрирован в ApplicationContext.'''
| |
|
| |
| URLEditor - строковое представление URL в экземпляр java.net.URL
| |
|
| |
| == CustomEditorConfigurer ==
| |
| В JDK 5 или более новых версиях предлагается класс PropertyEditorSupport, который могут расширять специальные редакторы свойств, оставляя вам реализацию только одного метода setAsText().
| |
| Чтобы особый класс редактора можно было применять в приложении, его понадобится зарегистрировать в ApplicationContext с использованием CustomEditorConfigurer.
| |
|
| |
| == StopWatch == | | == StopWatch == |
| org.springframework.util.StopWatch - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения. | | org.springframework.util.StopWatch - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения. |
Строка 341: |
Строка 169: |
| } | | } |
| stopWatch.stop(); | | stopWatch.stop(); |
| System. out. println ( "100000 gets took " + stopWatch. getTotalTimeMillis () + " ms");
| |
| == AbstractApplicationContext ==
| |
| === AbstractApplicationContext.registerShutdownHook ===
| |
| registerShutdownHook - создать перехватчик завершения (shutdown hook) - поток, который выполняется непосредственно перед завершением приложения.
| |
| Это отличный способ вызвать метод destroy () вашего класса AbstractApplicationContext (который расширяется всеми конкретными реализациями ApplicationContext).
| |
|
| |
| Пример для автономного приложения:
| |
| ctx.load("classpath:META-INF/spring/app-context-annotation.xml");
| |
| ctx.registerShutdownHook();
| |
| ctx.refresh();
| |
| Можно определить бин, который автоматом сделает тоже самое
| |
| <nowiki><bean id="shutdownHook" class="ShutdownHookBean"/></nowiki>
| |
| где ShutdownHookBean implements ApplicationContextAware
| |
| с таким методом setApplicationContext:
| |
| if (ctx instanceof GenericApplicationContext) {
| |
| ((GenericApplicationContext)ctx).registerShutdownHook();
| |
| }
| |
|
| |
| === AbstractApplicationContext.destroy ===
| |
| Единственный недостаток обратных вызовов уничтожения в Spring связан с тем, что они не запускаются автоматически, т.е. перед закрытием приложения нужно не забыть вызвать AbstractApplicationContext.destroy(). Когда приложение выполняется как сервлет, указанный метод destroy() можно вызвать в методе destroy() сервлета. Однако в автономном приложении все не так просто, особенно при наличии множества точек выхода из приложения.
| |
| К счастью, решение есть. Java позволяет создать перехватчик завершения (shutdown hook). См. AbstractApplicationContext.registerShutdownHook
| |
|
| |
| == BeanNameAware ==
| |
| Интерфейс BeanNameAware, который бин может реализовать, чтобы получить свое имя, имеет единственный метод: setBeanName (String)
| |
| == ApplicationContextAware ==
| |
| Интерфейс ApplicationContextAware, который бин может реализовать, чтобы получить ссылку на контекст ApplicationContext, который их сконфигурировал.
| |
| Имеет метод:
| |
| setApplicationContext(ApplicationContext ctx) throws BeansException
| |
| == FactoryBean ==
| |
| В интерфейсе FactoryBean объявлены три метода: getObject(), getObjectType() и isSingleton().
| |
| Реализуя этот интерфейс и добавив в него управляющее свойство, можно создавать бины с соответствующего типа, которые будут возвращаться через getObject().
| |
| Пример получения нужного типа объекта:
| |
| MessageDigest digest = (MessageDigest)ctx.getBean("shaDigest");
| |
| Пример получения фабрики бинов для генерации нужного объекта вручную:
| |
| MessageDigestFactoryBean factoryBean = (MessageDigestFactoryBean)ctx.getBean("&shaDigest");
| |
| == MessageSource ==
| |
| определяет 3 типа вызова getМessage():
| |
| getMessage(String, Object[], Locale)
| |
| getMessage(String, Object[] , String, Locale)
| |
| getMessage(MessageSourceResolvable, Locale)
| |
|
| |
| Реализации: ApplicationContext, ResourceBundleMessageSource, ReloadableResourceBundleMessageSource и StaticMessageSource.
| |
|
| |
| Реализация StaticMessageSource не должна применяться в производственном приложении, поскольку ее нельзя конфигурировать внешне.
| |
|
| |
| Реализация ResourceBundleMessageSource загружает сообщения с использованием Jаvа-класса ResourceBundle.
| |
|
| |
| Реализация ReloadableResourceBundleMessageSource в основном такая же, но поддерживает запланированную перезагрузку лежащих в основе исходных файлов.
| |
|
| |
| Все три реализации MessageSource также реализуют еще один интерфейс по имени HierarchicalMessageSource, который позволяет вкладывать друг в друга экземпляры MessageSource.
| |
|
| |
| Чтобы задействовать поддержку MessageSource, предоставляемую ApplicationContext, в конфигурации должен быть определен бин типа MessageSource с именем messageSource. Контекст ApplicationContext берет этот MessageSource и вкладывает его внутрь себя самого, разрешая доступ к сообщениям с применением ApplicationContext.
| |
| Пример:
| |
| <nowiki> <bean id = "messageSource"
| |
| class="org.springframework.context.support.ResourceBundleMessageSource"
| |
| p:basenames-ref = "basenames"/>
| |
| <util:list id="basenames">
| |
| <value>buttons</value>
| |
| <value>labels</value>
| |
| </util:list></nowiki>
| |
| Файлы должны называться labels_en.properties labels_ru.properties и buttons_en.properties buttons_ru.properties.
| |
|
| |
| == ApplicationEvent ==
| |
| Событие - это класс, производный от ApplicationEvent, который сам является производным от java.util.EventObject.
| |
| Любой бин может прослушивать события, реализовав интерфейс ApplicationListener<T>;
| |
| при этом AppliсаtionContext автоматически регистрирует любой сконфигурированный бин,
| |
| который реализует данный интерфейс, в качестве прослушивателя.
| |
|
| |
| Публикация события через ApplicationContext:
| |
| ApplicationContext ctx = ...;
| |
| ctx.publishEvent(new ApplicationEvent(...));
| |
|
| |
| == Resource ==
| |
| В интерфейсе Resource определены десять самоочевидных методов: contentLength(), exists(), getDescription(), getFile(), getFileName(), getURI(), getURL(), isOpen(), isReadble() и lastModified(). В дополнение к этим десяти методам имеется еще один, не столь самоочевидный: createRelative(). Метод createRelative() создает новый экземпляр Resource, используя путь относительно экземпляра, на котором он вызывается.
| |
|
| |
| В большинстве случаев будет применяться одна из встроенных реализаций для доступа к файлу (класс FileSystemResource), пути классов (класс ClassPathResource) или URL-pecypcaм (класс UrlResource).
| |
|
| |
| == Environment ==
| |
| Для установки активного профиля необходимо обратиться к интерфейсу Environment. Этот интерфейс представляет собой уровень абстракции, предназначенный для инкапсуляции среды выполняющегося приложения Spring. Кроме профилей интерфейс Environment инкапсулирует и другие ключевые порuии информаuии - свойства. Свойства служат для сохранения лежащей в основе приложения конфигурации среды, куда входит местоположение папки приложения, параметры подключения к базе данных и т.д.
| |
| см. beans profile
| |
|
| |
| = АОП =
| |
| == Типы АОП ==
| |
| Различают два типа АОП: статическое и динамическое.
| |
| При статическом АОП, таком как предоставляемое механизмами связывания во время компиляции AspectJ, сквозная функциональность применяется к коду на этапе компиляции, и ее нельзя изменить без модификации кода и повторной компиляции.
| |
| == Концепция ==
| |
| Joiлpoint: Точка соединения - это четко определенная точка во время выполнения приложения. Типовые примеры точек соединения включают обращение к методу, собственно вызов метода (Method Invocation), инициализацию класса и создание экземпляра объекта.
| |
|
| |
| Advice: Фрагмент кода, который должен выполняться в отдельной точке соединения, представляет собой совет (advice), определенный методом в классе.
| |
|
| |
| Pointcut: Срез (pointcut) - это коллекция точек соединения, которая используется для определения ситуации, когда совет должен быть выполнен.
| |
|
| |
| Aspect: Аспект (aspect) - это комбинация совета и срезов, инкапсулированных в классе.
| |
|
| |
| Weaving: Связывание (weaving) представляет собой процесс вставки аспектов в определенную точку внутри кода приложения.
| |
|
| |
| Target: Цель (target) - это объект, поток выполнения которого изменяется каким-то процессом АОП.
| |
|
| |
| Introduction: Введение (introduction) представляет собой процесс, посредством которого можно изменить структуру объекта за счет помещения в него дополнительных методов или полей.
| |
|
| |
| [[Файл:Spring-AOP-interfaces.png|безрамки|800x800пкс]]
| |
|
| |
| == MethodInvocation ==
| |
| Представляет вызов метода, снабжаемый советом, и с помощью этого объекта мы управляем тем, когда вызову метода разрешено продолжаться.
| |
|
| |
| == ProxyFactory ==
| |
| Используется для создания прокси целевого объекта и одновременного его связывания с советом.
| |
|
| |
| Пример:
| |
| MessageWriter target = new MessageWriter(); // целевой объект
| |
| ProxyFactory pf = new ProxyFactory();
| |
| pf.addAdvice(new MessageDecorator()); // установка совета
| |
| pf.setTarget(target); // установка целевого объекта
| |
| MessageWriter proxy = (MessageWriter) pf.getProxy(); // получение прокси-объекта с советом
| |
| proxy.writeMessage(); // вызов метода прокти-объекта
| |
|
| |
| Один и тот же экземпляр ProxyFactory можно применять для создания множества прокси, каждый из которых имеет отличающийся аспект.
| |
| Чтобы помочь в этом, в ProxyFactory предусмотрены методы removeAdvice() и removeAdvisor(), позволяющие удалять из ProxyFactory любой совет или реализации Advisor, которые ранее были добавлены.
| |
|
| |
| Для проверки, имеет ли ProxyFactory конкретный присоединенный к нему совет, вызовите метод adviceincluded(), передав ему проверяемый объект совета.
| |
|
| |
| == Advisor ==
| |
| В реализации АОП в Spring аспект представляется экземпляром клacca, который реализует интерфейс Advisor.
| |
| Платформа Spring предлагает удобные реализации Advisor, которые можно применять в своих приложениях, устраняя необходимость в создании специальных реализаций Advisor.
| |
| Существуют два подчиненных интерфейса Advisor: IntroductionAdvisor и PointcutAdvisor.
| |
|
| |
| Если необходим дополнительный контроль над созданием Advisor или нужно добавить введение к прокси, создайте
| |
| реализацию Advisor самостоятельно и используйте метод addAdvisor() класса ProxyFactory.
| |
|
| |
| == MethodВeforeAdvice ==
| |
| Совет "перед" (before), можно осущест влять специальную обработку перед входом в точку соединения.
| |
|
| |
| void before(Method method, Object(] args, Object target) throws ThrowaЫe
| |
|
| |
| == AfterReturningAdvice ==
| |
| Совет "после возврата" (after returning) выполняется после завершения выполнения вызова метода в точке соединения и возврата значения.
| |
|
| |
| Учитывая, что метод уже выполнен, переданные ему аргументы модифицировать невозможно
| |
|
| |
| В совете "после возврата" невозможно модифицировать возвращаемое значение.
| |
|
| |
| Несмотря на то что совет "после возврата" не позволяет изменять возвращаемое значение вызова метода, можно сгенерировать исключение, которое будет передано вверх по стеку вместо возвращаемого значения.
| |
|
| |
| void afterReturning(Object returnValue, Method method, Object[] args,Object target) throws Throwble
| |
|
| |
| == AfterAdvice ==
| |
| Совет "после возврата" выполняется только в случае нормального завершения метода, снабженного советом.
| |
| Однако совет "после" (after(finally)) будет выполняться вне зависимости от результата метода, снабженного этим советом.
| |
|
| |
| == Methodinterceptor ==
| |
| В Spring совет "вокруг" (around) моделируется с использованием стандарта Альянса АОП для nерехватчика метода.
| |
|
| |
| Интерфейс Methodinterceptor - это стандартный интерфейс Альянса АОП для реализации совета "вокруг" для точек соединения вызовов методов.
| |
| Object invoke(Methodinvocation invocation) throws Throwable
| |
|
| |
| == ThrowsAdvice ==
| |
| Совет "перехват" (throws) выполняется после возврата из вызова метода, но только в случае, если во время вызова было сгенерировано исключение.
| |
|
| |
| Первый метод afterThrowing () в классе принимает единственный аргумент типа Exception.
| |
| В нем можно указывать любой тип исключения, и этот метод идеально подходит, когда вас не интересует метод, сгенерировавший исключение, или переданные ему аргументы.
| |
| void afterThrowing(Exception1 ех) throws Throwable
| |
| Во втором методе afterThrowing () мы объявили четыре аргумента для указания метода, сгенерировавшего исключение, аргументов, переданных этому методу, и цели вызова метода. Порядок следования аргументов в этом методе важен, и они должны быть указаны все четыре.
| |
| void afterThrowing(Method method, Object[] args, Object target, Exception1 ех) throws Throwable
| |
|
| |
| Exception1 - это конкретный тип исключения и все его подтипы для перехвата.
| |
|
| |
| Spring использует метод, сигнатура которого в наибольшей степени соответствует типу исключения.
| |
|
| |
| В ситуации, когда совет "перехват" имеет дело с двумя методами afterThrowing(), причем оба объявлены с тем самым типом Exception,
| |
| но один принимает единственный аргумент, а другой - четыре аргумента, платформа Spring вызывает метод afterThrowing() с четырьмя аргументами.
| |
|
| |
| == IntroductionInterceptor ==
| |
| Платформа Spring моделирует "введения" (introduction) как специальные типы перехватчиков. Используя перехватчик введения, можно указать реализацию методов, которые должны быть введены советом
| |
|
| |
| == Pointcut ==
| |
|
| |
| public interface Pointcut {
| |
| ClassFilter getClassFilter ();
| |
| Method Мatcher getMethodМatcher();
| |
| }
| |
|
| |
| В версии Spring 4.0 предлагаются восемь реализаций интерфейса Pointcut:
| |
|
| |
| AnnotationМatchingPointcut - Срез, который ищет специфическую Jаvа аннотацию в классе или методе.
| |
|
| |
| AspectJExpressionPointcut - Срез, который использует средство связывания AspectJ для оценки выражения среза, представлен ного с помощью синтаксиса AspectJ
| |
|
| |
| ComposablePointcut - применяется для объединения двух и более срезов с помощью таких операций, как union() и intersection()
| |
|
| |
| ControlFlowPointcut - срез, предназначенный для специального случая, который соответствует всем методам в потоке управления другого метода - т.е . любому методу, который вызван прямо или косвенно в результате выполнения другого метода
| |
|
| |
| DynamicMethodМatcherPointcut - служит базовым классом для построения динамических срезов
| |
|
| |
| JdkRegexpMethodPointcut - позволяет определять срезы с использованием подцержки регулярных выражений JDK 1.4
| |
|
| |
| NameMatchMethodPointcut - срез, который выполняет простое сопоставление со списком имен методов
| |
|
| |
| StaticMethodМatcherPointcut - служит базовым классом для построения статических срезов
| |
|
| |
| [[Файл:Pointcut-hierarchy.png|безрамки|800x800пкс]]
| |
|
| |
| == ClassFilter ==
| |
| boolean matches(Class<?> clazz);
| |
|
| |
| == MethodМatcher ==
| |
| public interface MethodМatcher {
| |
| boolean matches(Method m, Class<?> targetClass);
| |
| boolean isRuntime();
| |
| boolean matches(Method m, Class<?> targetClass, Object[J args);
| |
| }
| |
|
| |
| Перед использованием MethodMatcher платформа Spring вызывает isRuntime() для выяснения, является ли MethodМatcher статическим, на что указывает возвращенное значение false, или же динамическим, что отражается значением true.
| |
|
| |
| Для статического среза Spring вызывает метод matches(Method, Class<T>) интерфейса MethodMatcher по одному разу для каждого метода целевого объекта, кешируя возвращаемое значение для послед у ющих обращений к этому методу.
| |
|
| |
| Для динамических в дополнении в первому вызову с результатом true платформа Spring проводит дальнейшую проверку для каждого вызова метода, используя matches(Method, Class<T>, Obj ect[]).
| |
Конфигурация XML
context:component-scan
Дескриптор <context:component-scan> сообщает Spring о необходимости
сканирования кода на предмет внедряемых бинов, аннотированных с помощью
@Component, @Controller, @Repository и @Service, а также поддерживающих
аннотации @Autowired и @Inject в указанном пакете (и всех eгo внутренних па
кетах). В дескрипторе <context:component-scan> можно определить множество
пакетов, используя в качестве разделителя запятую, точку запятой или пробел.
Кроме того, для более детализированного управления этот дескриптор поддерживает
включение и исключение сканирования компонентов.
Также можно указать пакет для сканирования через установку атрибута base-package.
Еще можно указать исключения через context:exclude-filter.
bean
bean/property
name - Имя свойства бина
value - значение (простой тип)
До версии 2.5:
ref - ссылка на другой бин по id
Применение атрибута local означает, что дескриптор ref всегда просматривает только идентификатор бина и никогда не принимает во внимание его псевдонимы:
<ref local="test"/>
Более того, определение бина должно существовать в том же самом ХМL-файле конфигурации.
Пример ссылки на бин (ссылка текущий, дочерний, родительский контекст)
<ref bean="newBean"/>
Пример ссылки на бин родительского контекста
<ref parent="newBean"/>
С версии 2.5: конфигурировать можно не через property, а в самом bean так:
p:<тут имя свойства>-ref="id другого бина"
или так
p:<тут имя свойства>="простое значение"
Через SpEL:
p:name = "#{injectSimpleConfig.name}"
bean/property/map
Пример:
<property name="map">
<map>
<entry key="v1">
<value>Hello World!</value>
</entry>
<entry key="refToBean">
<ref local="localBeanId"/>
</entry>
</map>
</property>
bean/property/set
<property name="set">
<set>
<value>Hello World 1 </value>
<ref local="oracle" />
</set>
</property>
bean/property/list
<property name="list">
<list>
<value>Hello World!</value>
<ref local="localBeanId"/>
</list>
</property>
bean/property/props
Дескриптор <props> позволяет передавать в качестве значений только String,
потому что класс Properties разрешает только значения свойств типа String.
Пример:
<property name="props">
<props>
<prop key="firstName">Sasha</prop>
<prop key="secondName">V.</prop>
</props>
</property>
bean/constructor-arg
До версии 3.1:
constructor-arg определяет Constructor Injection.
Всегда лучше применять атрибут index, чтобы избежать путаницы между параметрами.
С версии 3.1: можно применять в bean выражение вида c:<свойство>=<значение>
или _<digit> - как указание индекса аргумента конструктора
<bean id="message" class="java.lang.String" с:_O="message"/>
Если есть 2 конструктора с одинаковыми именами параметров, то можно указать тип
<constructor-arg type="int"><value>1</value><constructor-arg>
bean/lookup-method
Пример Method Injection:
<bean id="abstractLookupBean" class="com.a.AЬstractLookupDemoBean">
<lookup-method name="getMyHelper" bean="helper"/>
</bean>
util
Пространство имен util, предоставляемое Spring, для объявления бинов, хранящих свойства коллекций.
util:map
<util:map id="map" map-class = "java.util.HashMap">
<entry key = "someValue">
<value>Hello World!</value>
</entry>
<entry key="someBean">
<ref bean="beanId"/>
</entry>
</util:map>
util:properties
<util:properties id="props">
<prop key="firstName">Sasha</prop>
<prop key = "secondName">V.</prop>
</util:properties>
util:set
<util: set id="set">
<value>Hello World!</value>
<ref bean = "oracle"/>
</util: set>
util:list
<util:list id="list">
<value>Hello World!</value>
<ref bean="oracle"/>
</util:list>
Кофигурация аннотациями
@Autowired
Если указано на setter, то происходит автоматическое связывание.
Если указано на construcor, то происходит автоматическая передача параметра, пример:
@Autowired
public NewConstructor (@Value ( "message") String message) {
this.message = message;
}
Аннотация @Autowired может быть применена только к одному из методов конструкторов.
@Inject
В спринг аналогична автоматическому связыванию (JSR-299).
@Resource
Пример - @Resource (name = "messageProvider") указывается для поддержки автоматического связывания. (JSR-250)
@Value
Предназначена для определения значения, подлежащего внедрению.
Свойства:
@Value("32")
private int age;
Через SpEL:
@Value("#{injectSimpleConfig.name}")
Жесткое кодирование значения не является удачной идеей, т.к. его изменение влечет за собой перекомпиляцию программы.
@Service
Пример - @Service("messageRenderer") указывает, что этот бин предоставляет службы,
которые могут требоваться другим бинам; в качестве параметра аннотации передается имя бина.
@Component
@Component("injectSimpleConfig")
@Service является специализацией @Component, отражающей тот факт, что аннотированный класс предоставляет бизнес-службу другим уровням внутри приложения.
Классы Spring
StopWatch
org.springframework.util.StopWatch - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения.
StopWatch stopWatch = new StopWatch();
stopWatch.start("demo");
for (int х = О; х < 100000; х++) {
MyHelper helper = bean.getMyHelper();
helper.doSomethingHelpful();
}
stopWatch.stop();