You can often find yourself in a situation with many similar proxy definitions, especially when defining transactional proxies. By using parent and child bean definitions along with inner bean definitions, you can get much cleaner and more concise proxy definitions.
First, create a parent, template bean definition for the proxy, as shown below:
<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>
It is never instantiated on its own, so it may not be complete. Then, each proxy that needs to be created will be a child bean definition, wrapping the proxy target as an internal bean definition, since the target is never used on its own. The following example shows a child bean like this:
<bean id="myService" parent="txProxyTemplate">
<property name="target">
<bean class="org.springframework.samples.MyServiceImpl">
</bean>
</property>
</bean>
You can override the properties of the parent template. In the following example, we override the transaction propagation settings:
<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>
Note that in the parent bean example, we explicitly marked the parent bean definition as abstract by setting the
abstract
attribute to true
, so that its instance will actually was never actually created.
Application contexts (but not simple bean factories) by default pre-create all singleton instances. So it's
important (at least in the case of singleton beans) that if you have a (parent) bean definition that you're only
going to use as a template, and that definition defines a class, then you need to make sure that the
abstract
attribute is set to true
. Otherwise, the application context will actually try to
pre-create an instance of it.
Creating an AOP proxy programmatically using ProxyFactory
Creating AOP proxies programmatically using Spring is very easy. This will allow you to use the Spring AOP module without depending on the Spring IoC module.
Interfaces implemented by the target are automatically proxied. The following listing demonstrates creating a proxy for a target with one interceptor and one advisor:
ProxyFactory factory = new ProxyFactory(myBusinessInterfaceImpl);
factory.addAdvice(myMethodInterceptor);
factory.addAdvisor(myAdvisor);
MyBusinessInterface tb = (MyBusinessInterface) factory.getProxy();
val factory = ProxyFactory(myBusinessInterfaceImpl)
factory.addAdvice(myMethodInterceptor)
factory.addAdvisor(myAdvisor)
val tb = factory.proxy as MyBusinessInterface
The first step is to create an object of type org.springframework.aop.framework.ProxyFactory
. It can be
created using a target object, as in the previous example, or you can specify the interfaces that will be proxied in
an alternative constructor.
You can add tips (with interceptors as a specialized type of advice), advisors, or both, and manipulate them
throughout the ProxyFactory
lifecycle. If you add IntroductionInterceptionAroundAdvisor
,
the proxy can be forced to implement additional interfaces.
ProxyFactory
also has convenience methods (inherited from AdvisedSupport
) that allow you to
add other types of advice, such as the "before" advice and the "throw exception" advice. AdvisedSupport
is the superclass of ProxyFactory
and ProxyFactoryBean
.