Часто можна опинитися в ситуації з безліччю схожих визначень проксі, особливо у визначенні транзакційних проксі. Якщо використовувати визначення батьківських та дочірніх бінів, поряд із визначеннями внутрішніх бінів можна отримати набагато чистіші та лаконічні визначення проксі.

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

<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 як MyBusinessInterface

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

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

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

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