До сих пор мы рассматривали явное создание прокси АОП с помощью ProxyFactoryBean или аналогичного бина-фабрики.

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

В этой модели вы устанавливаете некоторые специфические определения бинов в вашем XML-файле определения бина для конфигурирования инфраструктуры авто-прокси. Это позволяет объявлять цели, подходящие для автопроксирования. Нет необходимости использовать ProxyFactoryBean.

Сделать это можно двумя способами:

  • С помощью создателя авто-прокси, которое ссылается на специфические бины в текущем контексте.

  • Особый случай создания авто-прокси, который заслуживает отдельного рассмотрения: создание авто-прокси на основе атрибутов метаданных на уровне источника.

Определения бинов c авто-прокси

В этом разделе рассматриваются создатели авто-прокси, предоставляемые пакетом org.springframework.aop.framework.autoproxy.

BeanNameAutoProxyCreator

Класс BeanNameAutoProxyCreator – это BeanPostProcessor, который автоматически создает прокси АОП для бинов с именами, которые соответствуют буквенным значениям или подстановочным знакам. В следующем примере показано, как создать бин BeanNameAutoProxyCreator:

<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
    <property name="beanNames" value="jdk*,onlyJdk"/>
    <property name="interceptorNames">
        <list>
            <value>myInterceptor</value>
        </list>
    </property>
</bean>

Как и в ProxyFactoryBean, здесь есть свойство interceptorNames, а не список перехватчиков, для обеспечения корректной логкики работы советников-прототипов. Именованные "перехватчики" могут быть советниками или советами любого типа.

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

Определения бинов, имена которых совпадают, такие как jdkMyBean и onlyJdk в предыдущем примере, являются обычными определениями бинов с целевым классом. Прокси АОП автоматически создается с помощью BeanNameAutoProxyCreator. Этот же совет применим ко всем соответствующим бинам. Обратите внимание, что если используются советники (а не перехватчик в предыдущем примере), срезы можно по-разному применять к разным бинам.

DefaultAdvisorAutoProxyCreator

Более общим, но чрезвычайно эффективным создателем авто-прокси является DefaultAdvisorAutoProxyCreator. Он автоматически применяет подходящие советники в текущем контексте, без необходимости включать конкретные имена бинов в определение бина советника с авто-прокси. Он предлагает те же преимущества последовательной конфигурации и избежания дублирования, что и BeanNameAutoProxyCreator.

Использование этого механизма включает в себя:

  • Задание определения бина DefaultAdvisorAutoProxyCreator.

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

DefaultAdvisorAutoProxyCreator автоматически вычисляет срез, содержащийся в каждом советнике, чтобы узнать, какой совет (если таковой имеется) он должен применить к каждому бизнес-объекту (например, businessObject1 и businessObject2 в примере).

Это означает, что любое количество советников может быть автоматически применено к каждому бизнес-объекту. Если ни один из советников не совпадет ни с одним методом бизнес-объекта, объект не будет проксирован. По мере добавления определений бина для новых бизнес-объектов, они автоматически проксируются, если это необходимо.

Преимущество автопроксирования в целом состоит в том, что оно не позволяет вызывающему коду или зависимостям получать объект, не снабженный советом. Вызов getBean("businessObject1") для этого ApplicationContext возвращает прокси АОП, а не целевой бизнес-объект. (Подход с "внутренним бином", показанный ранее, также предоставляет это преимущество).

В следующем примере создается бин DefaultAdvisorAutoProxyCreator и другие элементы, рассмотренные в этом разделе:

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
    <property name="transactionInterceptor" ref="transactionInterceptor"/>
</bean>
<bean id="customAdvisor" class="com.mycompany.MyAdvisor"/>
<bean id="businessObject1" class="com.mycompany.BusinessObject1">
    <!-- Свойства опущены  -->
</bean>
<bean id="businessObject2" class="com.mycompany.BusinessObject2"/>

DefaultAdvisorAutoProxyCreator очень полезен, если вам нужно последовательно применять один и тот же совет ко многим бизнес-объектам. После того как определения инфраструктуры созданы, можно добавлять новые бизнес-объекты без включения специфической конфигурации прокси. Вы также можете с легкостью добавить дополнительные аспекты (например, аспекты трассировки или мониторинга производительности) с минимальными изменениями в конфигурации.

DefaultAdvisorAutoProxyCreator предлагает поддержку фильтрации (путем использования соглашения об именовании, чтобы вычислялись только определенные советники, что позволит использовать множество по-разному настроенных AdvisorAutoProxyCreator в одной фабрике) и упорядочивания. Советники могут реализовывать интерфейс org.springframework.core.Ordered для обеспечения надлежащего упорядочивания, если это является проблемой. TransactionAttributeSourceAdvisor, используемый в предыдущем примере, имеет настраиваемое значение упорядоченности. По умолчанию используется значение "неупорядоченный".