KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > springframework > transaction > interceptor > TransactionProxyFactoryBean


1 /*
2  * Copyright 2002-2006 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.springframework.transaction.interceptor;
18
19 import java.util.Properties JavaDoc;
20
21 import org.springframework.aop.Pointcut;
22 import org.springframework.aop.framework.AbstractSingletonProxyFactoryBean;
23 import org.springframework.aop.support.DefaultPointcutAdvisor;
24 import org.springframework.beans.factory.BeanFactory;
25 import org.springframework.beans.factory.BeanFactoryAware;
26 import org.springframework.beans.factory.BeanFactoryUtils;
27 import org.springframework.beans.factory.FactoryBean;
28 import org.springframework.beans.factory.ListableBeanFactory;
29 import org.springframework.transaction.PlatformTransactionManager;
30
31 /**
32  * Proxy factory bean for simplified declarative transaction handling.
33  * This is a convenient alternative to a standard AOP
34  * {@link org.springframework.aop.framework.ProxyFactoryBean}
35  * with a separate {@link TransactionInterceptor} definition.
36  *
37  * <p>This class is intended to cover the <i>typical</i> case of declarative
38  * transaction demarcation: namely, wrapping a singleton target object with a
39  * transactional proxy, proxying all the interfaces that the target implements.
40  *
41  * <p>There are three main properties that need to be specified:
42  * <ul>
43  * <li>"transactionManager": the {@link PlatformTransactionManager} implementation to use
44  * (for example, a {@link org.springframework.transaction.jta.JtaTransactionManager} instance)
45  * <li>"target": the target object that a transactional proxy should be created for
46  * <li>"transactionAttributes": the transaction attributes (for example, propagation
47  * behavior and "readOnly" flag) per target method name (or method name pattern)
48  * </ul>
49  *
50  * <p>If the "transactionManager" property is not set explicitly and this {@link FactoryBean}
51  * is running in a {@link ListableBeanFactory}, a single matching bean of type
52  * {@link PlatformTransactionManager} will be fetched from the {@link BeanFactory}.
53  *
54  * <p>In contrast to {@link TransactionInterceptor}, the transaction attributes are
55  * specified as properties, with method names as keys and transaction attribute
56  * descriptors as values. Method names are always applied to the target class.
57  *
58  * <p>Internally, a {@link TransactionInterceptor} instance is used, but the user of this
59  * class does not have to care. Optionally, a method pointcut can be specified
60  * to cause conditional invocation of the underlying {@link TransactionInterceptor}.
61  *
62  * <p>The "preInterceptors" and "postInterceptors" properties can be set to add
63  * additional interceptors to the mix, like
64  * {@link org.springframework.aop.interceptor.PerformanceMonitorInterceptor} or
65  * {@link org.springframework.orm.hibernate3.HibernateInterceptor} /
66  * {@link org.springframework.orm.jdo.JdoInterceptor}.
67  *
68  * <p><b>HINT:</b> This class is often used with parent / child bean definitions.
69  * Typically, you will define the transaction manager and default transaction
70  * attributes (for method name patterns) in an abstract parent bean definition,
71  * deriving concrete child bean definitions for specific target objects.
72  * This reduces the per-bean definition effort to a minimum.
73  *
74  * <pre code="class">
75  * &lt;bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
76  * abstract="true"&gt;
77  * &lt;property name="transactionManager" ref="transactionManager"/&gt;
78  * &lt;property name="transactionAttributes"&gt;
79  * &lt;props&gt;
80  * &lt;prop key="insert*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
81  * &lt;prop key="update*"&gt;PROPAGATION_REQUIRED&lt;/prop&gt;
82  * &lt;prop key="*"&gt;PROPAGATION_REQUIRED,readOnly&lt;/prop&gt;
83  * &lt;/props&gt;
84  * &lt;/property&gt;
85  * &lt;/bean&gt;
86  *
87  * &lt;bean id="myProxy" parent="baseTransactionProxy"&gt;
88  * &lt;property name="target" ref="myTarget"/&gt;
89  * &lt;/bean&gt;
90  *
91  * &lt;bean id="yourProxy" parent="baseTransactionProxy"&gt;
92  * &lt;property name="target" ref="yourTarget"/&gt;
93  * &lt;/bean&gt;</pre>
94  *
95  * @author Juergen Hoeller
96  * @author Dmitriy Kopylenko
97  * @author Rod Johnson
98  * @since 21.08.2003
99  * @see #setTransactionManager
100  * @see #setTarget
101  * @see #setTransactionAttributes
102  * @see TransactionInterceptor
103  * @see org.springframework.aop.framework.ProxyFactoryBean
104  */

105 public class TransactionProxyFactoryBean extends AbstractSingletonProxyFactoryBean
106         implements FactoryBean, BeanFactoryAware {
107
108     private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
109
110     private Pointcut pointcut;
111
112
113     /**
114      * Set the transaction manager. This will perform actual
115      * transaction management: This class is just a way of invoking it.
116      * @see TransactionInterceptor#setTransactionManager
117      */

118     public void setTransactionManager(PlatformTransactionManager transactionManager) {
119         this.transactionInterceptor.setTransactionManager(transactionManager);
120     }
121
122     /**
123      * Set properties with method names as keys and transaction attribute
124      * descriptors (parsed via TransactionAttributeEditor) as values:
125      * e.g. key = "myMethod", value = "PROPAGATION_REQUIRED,readOnly".
126      * <p>Note: Method names are always applied to the target class,
127      * no matter if defined in an interface or the class itself.
128      * <p>Internally, a NameMatchTransactionAttributeSource will be
129      * created from the given properties.
130      * @see #setTransactionAttributeSource
131      * @see TransactionInterceptor#setTransactionAttributes
132      * @see TransactionAttributeEditor
133      * @see NameMatchTransactionAttributeSource
134      */

135     public void setTransactionAttributes(Properties JavaDoc transactionAttributes) {
136         this.transactionInterceptor.setTransactionAttributes(transactionAttributes);
137     }
138
139     /**
140      * Set the transaction attribute source which is used to find transaction
141      * attributes. If specifying a String property value, a PropertyEditor
142      * will create a MethodMapTransactionAttributeSource from the value.
143      * @see #setTransactionAttributes
144      * @see TransactionInterceptor#setTransactionAttributeSource
145      * @see TransactionAttributeSourceEditor
146      * @see MethodMapTransactionAttributeSource
147      * @see NameMatchTransactionAttributeSource
148      * @see AttributesTransactionAttributeSource
149      * @see org.springframework.transaction.annotation.AnnotationTransactionAttributeSource
150      */

151     public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
152         this.transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);
153     }
154
155     /**
156      * Set a pointcut, i.e a bean that can cause conditional invocation
157      * of the TransactionInterceptor depending on method and attributes passed.
158      * Note: Additional interceptors are always invoked.
159      * @see #setPreInterceptors
160      * @see #setPostInterceptors
161      */

162     public void setPointcut(Pointcut pointcut) {
163         this.pointcut = pointcut;
164     }
165
166     /**
167      * This callback is optional: If running in a BeanFactory and no transaction
168      * manager has been set explicitly, a single matching bean of type
169      * PlatformTransactionManager will be fetched from the BeanFactory.
170      * @see org.springframework.beans.factory.BeanFactoryUtils#beanOfTypeIncludingAncestors
171      * @see org.springframework.transaction.PlatformTransactionManager
172      */

173     public void setBeanFactory(BeanFactory beanFactory) {
174         if (this.transactionInterceptor.getTransactionManager() == null &&
175                 beanFactory instanceof ListableBeanFactory) {
176             ListableBeanFactory lbf = (ListableBeanFactory) beanFactory;
177             PlatformTransactionManager ptm = (PlatformTransactionManager)
178                     BeanFactoryUtils.beanOfTypeIncludingAncestors(lbf, PlatformTransactionManager.class);
179             this.transactionInterceptor.setTransactionManager(ptm);
180         }
181     }
182
183
184     /**
185      * Creates an advisor for this FactoryBean's TransactionInterceptor.
186      */

187     protected Object JavaDoc createMainInterceptor() {
188         this.transactionInterceptor.afterPropertiesSet();
189         if (this.pointcut != null) {
190             return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor);
191         }
192         else {
193             // Rely on default pointcut.
194
return new TransactionAttributeSourceAdvisor(this.transactionInterceptor);
195         }
196     }
197
198 }
199
Popular Tags