Concise Proxy Definitions
尤其是在定义事务代理时,您可能会遇到许多类似的代理定义。使用父级和子级 Bean 定义以及内部 Bean 定义可以生成更简洁、更简洁的代理定义。
Especially when defining transactional proxies, you may end up with many similar proxy definitions. The use of parent and child bean definitions, along with inner bean definitions, can result in much cleaner and more concise proxy definitions.
首先,我们为代理创建父级模板 Bean 定义,如下所示:
First, we create a parent, template, bean definition for the proxy, as follows:
<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:
This is never instantiated itself, so it can actually be incomplete. Then, each proxy that needs to be created is a child bean definition, which wraps the target of the proxy as an inner bean definition, since the target is never used on its own anyway. The following example shows such a child bean:
<bean id="myService" parent="txProxyTemplate">
<property name="target">
<bean class="org.springframework.samples.MyServiceImpl">
</bean>
</property>
</bean>
您可以覆盖父级模板中的属性。在以下示例中,我们覆盖事务传播设置:
You can override properties from 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>
请注意,在父 bean 示例中,如 previously 所述,我们通过将 abstract
属性设为 true
来明确标记父 bean 定义为抽象,所以它可能实际上永远不会被实例化。默认情况下,应用程序上下文(但并非简单的 bean 工厂)预实例化所有单例。因此,很重要(至少对于单例 bean)的是,如果有一个打算仅用作模板的(父)bean 定义,并且此定义指定了一个类,那么你必须确保将 abstract
属性设为 true
。否则,应用程序上下文会实际尝试预实例化它。
Note that in the parent bean example, we explicitly marked the parent bean definition as
being abstract by setting the abstract
attribute to true
, as described
previously, so that it may not actually ever be
instantiated. Application contexts (but not simple bean factories), by default,
pre-instantiate all singletons. Therefore, it is important (at least for singleton beans)
that, if you have a (parent) bean definition that you intend to use only as a template,
and this definition specifies a class, you must make sure to set the abstract
attribute to true
. Otherwise, the application context actually tries to
pre-instantiate it.