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

Материал из Home Wiki
Перейти к навигации Перейти к поиску
(не показана 71 промежуточная версия этого же участника)
Строка 24: Строка 24:
должны создаваться только при их запросе приложением.
должны создаваться только при их запросе приложением.
  <nowiki> <beans ... default-lazy-init = "true">
  <nowiki> <beans ... default-lazy-init = "true">
      <bean ... />
  <bean ... />
      ...
  ...
    </beans></nowiki>
  </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 ==
Строка 52: Строка 39:
Также можно указать пакет для сканирования через установку атрибута 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 ==
Строка 86: Строка 65:
Пример:
Пример:
  <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 ====
Строка 140: Строка 119:
Пример 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:
Строка 167: Строка 146:
под названием 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.


Строка 180: Строка 159:
Наследование бинов:
Наследование бинов:
  <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 ===
Строка 197: Строка 176:
  <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"/>
=== bean factory-method ===
см. bean factory-bean


== util ==
== util ==
Строка 212: Строка 181:
=== 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>
== aop ==
<syntaxhighlight lang="xml">
  <aop:config>
    <aop:pointcut id="fooExecution" expression="execution(* foo*(int))"/>
    <aop:aspect ref = "advice">
      <aop:before pointcut-ref="fooExecution" method="simpleBeforeAdvice"/>
    </aop:aspect>
  </aop:config>
  <bean id="advice" class="MyAdvice"/>
  <bean id="myDependency" class="MyDependency"/>
  <bean id="myBean" class="MyBean">
    <property name="dep" ref="myDependency"/>
  </bean>
</syntaxhighlight>


= Кофигурация аннотациями =
= Кофигурация аннотациями =
Строка 287: Строка 242:
@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 - этот класс очень полезный в ситуациях, когда необходимо проводить простые оценки производительности и тестировать разрабатываемые приложения.
Строка 360: Строка 253:
  stopWatch.stop();
  stopWatch.stop();
  System. out. println ( "100000 gets took " + stopWatch. getTotalTimeMillis () + " ms");
  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(), передав ему проверяемый объект совета.
При подмешивании (mixin):
Вызов setOptimize(true) обеспечивает применение CBLIB, чтобы сработало наследование и подмешивание интерфейса. При использовании setOptimize(false) (по умолчанию) используется JDK для создания прокси и тогда применяется только интерфейс смеси.
setFrozen(true) запрещает смену совета (advice) для оптимизации.
exposeProxy ???
== ProxyFactoryBean ==
В АОП, реализованном платформой Spring, класс ProxyFactoryBean предоставляет декларативный способ кон­фигурирования ApplicationContext (и, следовательно, лежащего в осно­ве BeanFactory) при создании прокси АОП на основе определенных бинов Spring.
Пример декларативного вида для советов:
bean1 - все снабжается советом, т.к. нет никаких срезов.
bean2 - совет снабжается только на метод foo, т.к. есть срез.<syntaxhighlight lang="xml">
<bean id="myBean1" class="MyBean">
  <property name = "dep">
    <ref bean = "myDependencyl "/>
  </property>
</bean>
<bean id="myBean2" class="MyBean">
  <property name="dep">
    <ref bean="myDependency2 "/>
  </property>
</bean>
<bean id="myDependencyl" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target">
    <ref bean="myDependencyTarget" />
  </property>
  <property name="interceptorNames">
    <list>
      <value>advice</value>
    </list>
  </property>
</bean>
<bean id="myDependency2" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target">
    <ref bean="myDependencyTarget" />
  </property>
  <property name="interceptorNames">
    <list>
      <value>advisor</value>
    </list>
  </property>
</bean>
<bean id="advice" class="MyAdvice"/>
<bean id="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
  <property name="advice">
    <ref bean="advice"/>
  </property>
  <property name="pointcut">
    <bean class="org.springframework.aop.aspectj.AspectJExpressionPointcut">
      <property name="expression ">
        <value>execution(* foo*( .. ))</value>
      </property>
    </bean>
  </property>
</bean>
</syntaxhighlight>
Пример декларативного вида для введений:
<syntaxhighlight lang="xml">
<bean id="bean" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target">
    <bean class="TargetBean">
      <property name="name">
        <value>Sasha V.</value>
      </property>
    </bean>
  </property>
  <property name="interceptorNames">
    <list>
      <value>advisor</value>
    </list>
  </property>
  <property name="proxyTargetClass">
    <value>true</value>
  </property>
</bean>
<bean id="advisor" class="IsModifiedAdvisor"/>
</syntaxhighlight>
== 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пкс]]
== DefaultPointcutAdvisor ==
Класс DefaultPointcutAdvisor - это просто PointcutAdvisor для связывания одного Pointcut с одним Advice.
== 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[]).
<references />

Версия 13:07, 11 февраля 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>

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>

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

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();
System. out. println ( "100000 gets took " + stopWatch. getTotalTimeMillis () + " ms");