Pro Spring 4: различия между версиями

Материал из Home Wiki
Перейти к навигации Перейти к поиску
(не показано 37 промежуточных версий этого же участника)
Строка 24: Строка 24:
должны создаваться только при их запросе приложением.
должны создаваться только при их запросе приложением.
  <nowiki> <beans ... default-lazy-init = "true">
  <nowiki> <beans ... default-lazy-init = "true">
  <bean ... />
    <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>
  </beans></nowiki>
 
см. Environment
== context:component-scan ==
== context:component-scan ==
Дескриптор <context:component-scan> сообщает Spring о необходимости
Дескриптор <context:component-scan> сообщает Spring о необходимости
Строка 39: Строка 51:
Также можно указать пакет для сканирования через установку атрибута 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 ==
Строка 65: Строка 85:
Пример:
Пример:
  <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 ====
Строка 119: Строка 139:
Пример 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 ===
=== bean/replaced-method ===
  <nowiki> <bean id="replacementTarget" class="com.a.ReplacementTarget">
  <nowiki> <bean id="replacementTarget" class="com.a.ReplacementTarget">
    <replaced-method name="formatMessage" replacer="methodReplacer">
      <replaced-method name="formatMessage" replacer="methodReplacer">
      <arg-type>String</arg-type>
        <arg-type>String</arg-type>
    </replaced-method>
      </replaced-method>
  </bean></nowiki>
    </bean></nowiki>
=== bean name-алиасы ===
=== bean name-алиасы ===
Через name:
Через name:
Строка 146: Строка 166:
под названием beanB.
под названием beanB.
  <nowiki> <bean id="beanA" class="BeanA" depends-on="beanB"/>
  <nowiki> <bean id="beanA" class="BeanA" depends-on="beanB"/>
  <bean id="beanB" class="BeanB"/></nowiki>
    <bean id="beanB" class="BeanB"/></nowiki>
Во время разработки приложений такого подхода лучше избегать; вместо это­го определяйте зависимости с помощью контрактов Setter Injection и Constructor Injection.
Во время разработки приложений такого подхода лучше избегать; вместо это­го определяйте зависимости с помощью контрактов Setter Injection и Constructor Injection.


Строка 159: Строка 179:
Наследование бинов:
Наследование бинов:
  <nowiki> <bean id="inheritParent" class="SimpleBean" p:name="Name1" p:age="32"/>
  <nowiki> <bean id="inheritParent" class="SimpleBean" p:name="Name1" p:age="32"/>
  <bean id="inheritChild" class="SimpleBean" parent="inheritParent" р:аgе="ЗЗ"/></nowiki>
    <bean id="inheritChild" class="SimpleBean" parent="inheritParent" р:аgе="ЗЗ"/></nowiki>


=== bean abstract ===
=== bean abstract ===
Строка 176: Строка 196:
  <nowiki><bean id="dBean" class="BeanClass" destroy-method="destroy"/></nowiki>
  <nowiki><bean id="dBean" class="BeanClass" destroy-method="destroy"/></nowiki>
Аналоги: DisposableBean.destroy(), @PreDestroy
Аналоги: DisposableBean.destroy(), @PreDestroy
=== bean factory-bean ===
Иногда нужно создавать экземпляры компонентов JavaBean, которые были пре­доставлены приложением третьей стороны, не поддерживающим Spring.
Вы не зна­ете, как создавать экземпляр этого класса, но вам известно, что приложение третьей стороны предлагает класс, который можно использовать для получения экземпля­ра JavaBean, необходимого вашему приложению Spring.
<bean id="defaultDigest"
  factory-bean="defaultDigestFactory"
  factory-method="createinstance"/>


== util ==
== util ==
Строка 181: Строка 208:
=== 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>


= Кофигурация аннотациями =
= Кофигурация аннотациями =
Строка 242: Строка 269:
@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 - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения.
Строка 257: Строка 346:
registerShutdownHook - создать перехватчик завершения (shutdown hook) - поток, который выполняется непосредственно перед завершением приложения.
registerShutdownHook - создать перехватчик завершения (shutdown hook) - поток, который выполняется непосредственно перед завершением приложения.
Это отличный спо­соб вызвать метод destroy () вашего класса AbstractApplicationContext (кото­рый расширяется всеми конкретными реализациями ApplicationContext).
Это отличный спо­соб вызвать метод 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 ===
=== AbstractApplicationContext.destroy ===
Единственный недостаток обратных вызовов уничтожения в Spring связан с тем, что они не запускаются автоматически, т.е. перед закрытием приложения нужно не забыть вызвать AbstractApplicationContext.destroy(). Когда приложе­ние выполняется как сервлет, указанный метод destroy() можно вызвать в методе destroy() сервлета. Однако в автономном приложении все не так просто, особен­но при наличии множества точек выхода из приложения.
Единственный недостаток обратных вызовов уничтожения в Spring связан с тем, что они не запускаются автоматически, т.е. перед закрытием приложения нужно не забыть вызвать AbstractApplicationContext.destroy(). Когда приложе­ние выполняется как сервлет, указанный метод destroy() можно вызвать в методе destroy() сервлета. Однако в автономном приложении все не так просто, особен­но при наличии множества точек выхода из приложения.
Строка 267: Строка 369:
Имеет метод:
Имеет метод:
setApplicationContext(ApplicationContext ctx) throws BeansException
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) выполняется после завершения выполнения вызова метода в точке соединения и возврата значения.
Учитывая, что метод уже выполнен, переданные ему аргументы модифицировать невозможно
== AfterAdvice ==
Совет "после возврата" выполняется только в случае нормального завершения метода, снабженного советом.
Однако совет "после" (after(finally)) будет выполняться вне зависимости от ре­зультата метода, снабженного этим советом.
== Methodinterceptor ==
В Spring совет "вокруг" (around) моделируется с исполь­зованием стандарта Альянса АОП для nерехватчика метода.
Интерфейс Methodinterceptor - это стандартный интерфейс Альянса АОП для реализации совета "вокруг" для точек соединения вызовов методов.
Object invoke(Methodinvocation invocation) throws Throwable
== ThrowsAdvice ==
Совет "перехват" (throws) выполняется после возврата из вызова метода, но только в случае, если во время вызова было сгенерировано исключе­ние.
== IntroductionInterceptor ==
Платформа Spring моделирует "введения" (introduction) как специальные типы перехватчиков. Используя перехватчик введения, можно указать реали­зацию методов, которые должны быть введе­ны советом

Версия 05:34, 12 февраля 2017

Жизненный цикл Spring Bean

SpringBeanLifeCycle.png

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

beans

beans default-lazy-init

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

 <beans ... default-lazy-init = "true">
    <bean ... />
    ...
  </beans>

beans profile

Профиль заставляет Spring конфигурировать только тот контекст ApplicationContext, который определен, когда указанный профиль становится активным. Активируется опцией -Dspring.profiles.active=activeProfile Пример профиля:

 <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>

см. Environment

context:component-scan

Дескриптор <context:component-scan> сообщает Spring о необходимости сканирования кода на предмет внедряемых бинов, аннотированных с помощью @Component, @Controller, @Repository и @Service, а также поддерживающих аннотации @Autowired и @Inject в указанном пакете (и всех eгo внутренних па­ кетах). В дескрипторе <context:component-scan> можно определить множест­во пакетов, используя в качестве разделителя запятую, точку запятой или пробел. Кроме того, для более детализированного управления этот дескриптор поддержи­вает включение и исключение сканирования компонентов. Также можно указать пакет для сканирования через установку атрибута base-package. Еще можно указать исключения через context:exclude-filter.

context:property-placeholder

Дескриптор context:property-placeholder для загрузки свойств в Sрring-интерфейс Environment, который помещен в оболочку интерфейса ApplicationContext. Кроме того, мы применяем заполнители для внедрения зна­чений в бин AppProperty.

 <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>

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>

bean/replaced-method

 <bean id="replacementTarget" class="com.a.ReplacementTarget">
      <replaced-method name="formatMessage" replacer="methodReplacer">
        <arg-type>String</arg-type>
      </replaced-method>
    </bean>

bean name-алиасы

Через name:

<bean id="name1" name="name2 name3,name4;name5" class="java.lang.String"/>

Через alias:

<alias name = "namel" alias = "name6"/>

Извлечь список псевдонимов бина можно с помощью вызова метода ApplicationContext.getAliases(String) с передачей ему любого из имен бина или его идентификатора. Этот метод возвращает в виде массива String спи­сок псевдонимов, содержащий все псевдонимы кроме указанного при вызове.

bean scope

По умолчанию Spring устанавливает атрибут scope в singleton (одиночный). Область действия на уров­не prototype (прототип) заставляет Spring создавать новый экземпляр бина каждый раз, когда он запрашивается приложением. Пример:

<bean id="nonSingleton" class="java.lang.String" scope="prototype" c:_0="Sasha V."/>

bean depends-on

В следующей конфигурации мы утверждаем, что бин по имени beanA зависит от бина под названием beanB.

 <bean id="beanA" class="BeanA" depends-on="beanB"/>
    <bean id="beanB" class="BeanB"/>

Во время разработки приложений такого подхода лучше избегать; вместо это­го определяйте зависимости с помощью контрактов Setter Injection и Constructor Injection.

bean autowire

В атрибуте autowire для бина понадобится указать используемый режим автосвязывания. Платформа Spring поддерживает следующие режимы автосвязывания: byName, ЬуТуре, constructor, default и no (автосвязывание отключено; устанавливает­ся по умолчанию).

bean lazy-init

Атрибут lazy-init устанавливается в true, что­бы информировать Spring о необходимости создания экземпляра бина только при первом его запросе, а не во время начальной загрузки.

bean parent

Наследование бинов:

 <bean id="inheritParent" class="SimpleBean" p:name="Name1" p:age="32"/>
    <bean id="inheritChild" class="SimpleBean" parent="inheritParent" р:аgе="ЗЗ"/>

bean abstract

В случае если определение родительского бина не должно быть доступным для поиска из ApplicationContext, к дескриптору bean, объявляющему родительский бин, можно добавить атрибут abstract="true".

bean init-method

Атрибут init-method, который сообщает платформе Spring, что она должна вызвать метод init(), как только завершит конфигурирование бина.

<bean id="iBean" class="BeanClass" init-method="init"/>

Аналоги: InitializingBean.afterPropertiesSet(), @PostConstruct

bean destroy-method

Чтобы назначить метод для вызова во время уничтожения бина, нужно прос­то указать имя этого метода в атрибуте destroy-method дескриптора <bean> для бина. Платформа Spring вызывает этот метод непосредственно перед уничтожением одиночного экземпляра бина (она не будет вызывать этот метод для бинов с облас­тью действия на уровне прототипа).

<bean id="dBean" class="BeanClass" destroy-method="destroy"/>

Аналоги: DisposableBean.destroy(), @PreDestroy

bean factory-bean

Иногда нужно создавать экземпляры компонентов JavaBean, которые были пре­доставлены приложением третьей стороны, не поддерживающим Spring. Вы не зна­ете, как создавать экземпляр этого класса, но вам известно, что приложение третьей стороны предлагает класс, который можно использовать для получения экземпля­ра JavaBean, необходимого вашему приложению Spring.

<bean id="defaultDigest"
  factory-bean="defaultDigestFactory" 
  factory-method="createinstance"/>

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, отражающей тот факт, что аннотированный класс предоставляет бизнес-службу другим уровням внутри приложения.

@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

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

org.springframework.util.StopWatch - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения.

StopWatch stopWatch = new StopWatch();
stopWatch.start("demo");
for (int х = О; х < 100000; х++) {
  MyHelper helper = bean.getMyHelper();
  helper.doSomethingHelpful();
}
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();

Можно определить бин, который автоматом сделает тоже самое

<bean id="shutdownHook" class="ShutdownHookBean"/>

где 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. Пример:

 <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>

Файлы должны называться 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

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) выполняется после завершения выполнения вызова метода в точке соединения и возврата значения. Учитывая, что метод уже выполнен, переданные ему аргументы модифицировать невозможно

AfterAdvice

Совет "после возврата" выполняется только в случае нормального завершения метода, снабженного советом. Однако совет "после" (after(finally)) будет выполняться вне зависимости от ре­зультата метода, снабженного этим советом.

Methodinterceptor

В Spring совет "вокруг" (around) моделируется с исполь­зованием стандарта Альянса АОП для nерехватчика метода.

Интерфейс Methodinterceptor - это стандартный интерфейс Альянса АОП для реализации совета "вокруг" для точек соединения вызовов методов. Object invoke(Methodinvocation invocation) throws Throwable

ThrowsAdvice

Совет "перехват" (throws) выполняется после возврата из вызова метода, но только в случае, если во время вызова было сгенерировано исключе­ние.

IntroductionInterceptor

Платформа Spring моделирует "введения" (introduction) как специальные типы перехватчиков. Используя перехватчик введения, можно указать реали­зацию методов, которые должны быть введе­ны советом