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

Сначала создаем родительское, шаблонное определение бина для прокси, как показано ниже:

<bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
        <props>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

Его экземпляр никогда не создается сам по себе, поэтому оно может быть неполным. Затем, каждый прокси, который необходимо создать, будет представлять собой дочернее определение бина, оборачивающее цель прокси как внутреннее определение бина, поскольку цель никогда не используется сама по себе. В следующем примере показан такой дочерний бин:

<bean id="myService" parent="txProxyTemplate">
    <property name="target">
        <bean class="org.springframework.samples.MyServiceImpl">
        </bean>
    </property>
</bean>

Вы можете переопределять свойства родительского шаблона. В следующем примере мы переопределяем настройки распространения транзакций:

<bean id="mySpecialService" parent="txProxyTemplate">
    <property name="target">
        <bean class="org.springframework.samples.MySpecialServiceImpl">
        </bean>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="store*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

Обратите внимание, что в примере с родительским бином мы явно пометили определение родительского бина как абстрактное, установив атрибут abstract в true, с тем расчётом, чтоб его экземпляр на самом деле никогда не был создан. Контексты приложений (но не простые фабрики бинов) по умолчанию предварительно создают все экземпляры-одиночки. Поэтому важно (по крайней мере, в случае бинов-одиночек), что если у вас есть определение (родительского) бина, которое вы собираетесь использовать лишь в качестве шаблона, и этим определением определяется класс, то вам нужно убедиться, что атрибут abstract установлен в true. В противном случае, контекст приложения фактически будет пытаться предварительно создать его экземпляр.

Создание прокси АОП программно с помощью ProxyFactory

Создавать прокси АОП программно с помощью Spring очень легко. Это позволит вам использовать модуль Spring AOP без зависимости от модуля Spring IoC.

Интерфейсы, реализованные целевым объектом, автоматически проксируются. В следующем листинге продемонстрировано создание прокси для целевого объекта с одним перехватчиком и одним советником:

Java
ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);
factory.addAdvice(myMethodInterceptor);
factory.addAdvisor(myAdvisor);
MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();
Kotlin
val factory = ProxyFactory(myBusinessInterfaceImpl)
factory.addAdvice(myMethodInterceptor)
factory.addAdvisor(myAdvisor)
val tb = factory.proxy as MyBusinessInterface

Первым шагом является создание объекта типа org.springframework.aop.framework.ProxyFactory. Создает его можно с помощью целевого объекта, как в предыдущем примере, или указать интерфейсы, которые будут проксироваться, в альтернативном конструкторе.

Можно добавить советы (с перехватчиками как специализированным видом советов), советники или и то, и другое, и манипулировать ими на протяжении всего жизненного цикла ProxyFactory. Если добавить IntroductionInterceptionAroundAdvisor, то прокси в принудительном порядке может реализовать дополнительные интерфейсы.

В ProxyFactory также есть удобные методы (унаследованные от AdvisedSupport), которые позволяют добавлять другие типы советов, такие как совет "перед" и совет "генерация исключения". AdvisedSupport является суперклассом ProxyFactory и ProxyFactoryBean.

Интеграция создания прокси АОП с IoC-фреймворком является передовым подходом в большинстве приложений. Мы рекомендуем вынести во внешний файл конфигурацию из Java-кода с помощью АОП, как это следует делать в целом.