你也许需要许多相似的代理定义,特别是定义事务性代理的时候。使用父子bean定义,以及内部bean定义,可以让代理定义大大得到极大的简化。
首先从父bean开始,为代理bean创建bean定义模版:
<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本身将永远不会被初始化,所以实际上是不完整的。而后每个需要创建的代理都是这个bean定义的子bean定义,它们把代理的目标类包装为一个内部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属性把父bean定义标注为abstract,在前面的章节里有描述,这样它实际上不能被初始化。 缺省情况下应用程序上下文(不仅仅是bean工厂)将预先初始化所有的实例为单例。 因此下面这点是很重要的(至少对于单例bean来说),如果你有一个(父)bean定义你希望仅仅作为模版使用,而这个定义说明了一个类,你必须把abstract参数设置为true,否则应用程序上下文将试图预先初始化它。