|
Size: 4857
Comment:
|
← Revision 3 as of 2009-09-20 23:20:57 ⇥
Size: 4857
Comment: converted to 1.6 markup
|
| No differences found! | |
1. Make transactionInterceptor accessible from Spring IOC context.
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory"/>
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor"
p:transactionInterceptor-ref="transactionInterceptor"/>
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor"
p:transactionManager-ref="transactionManager"
p:transactionAttributeSource-ref="transactionAttributeSource"/>
<bean id="transactionAttributeSource"
class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource">
<constructor-arg value="false"/>
</bean>
2. Contribute transactional worker to components transformation chain.
3. Create TransactionalWorker.
1 public class TransactionalWorker implements ComponentClassTransformWorker {
2 private final TransactionInterceptor transactionInterceptor;
3 private final ComponentMethodAdvice advice = new ComponentMethodAdvice() {
4 public void advise(final ComponentMethodInvocation invocation) {
5 try {
6 transactionInterceptor.invoke(new MethodInvocationAdapter(invocation));
7 if (invocation.isFail()) {
8 throw new RuntimeException(invocation.getThrown(Throwable.class));
9 }
10 }
11 catch (RuntimeException ex) {
12 throw ex;
13 } catch (Throwable ex) {
14 throw new RuntimeException(ex);
15 }
16 }
17 };
18
19 public TransactionalWorker(TransactionInterceptor transactionInterceptor) {
20 this.transactionInterceptor = transactionInterceptor;
21 }
22
23 public void transform(ClassTransformation transformation, MutableComponentModel model) {
24 for (TransformMethodSignature sig : transformation.findMethodsWithAnnotation(Transactional.class)) {
25 transformation.advise(sig, advice);
26 }
27 }
28 }
4. Implement MethodInvocation adapter.
1 import org.aopalliance.intercept.MethodInvocation;
2 import org.apache.tapestry.services.ComponentMethodInvocation;
3
4 import java.lang.reflect.AccessibleObject;
5 import java.lang.reflect.Method;
6
7 class MethodInvocationAdapter implements MethodInvocation {
8 private final ComponentMethodInvocation invocation;
9
10 public MethodInvocationAdapter(ComponentMethodInvocation invocation) {
11 this.invocation = invocation;
12 }
13
14 public Object getThis() {
15 return invocation.getComponentResources().getComponent();
16 }
17
18 public Method getMethod() {
19 Method method = BeanUtils.findDeclaredMethod(getThisClass(), invocation.getMethodName(), getParameterTypes());
20 if (method != null) {
21 return method;
22 }
23 throw new RuntimeException(invocation.getMethodName() + " not found");
24 }
25
26 private Class getThisClass() {
27 Class clazz = getThis().getClass();
28 try {
29 return Class.forName(clazz.getName()); // ClassLoader issue
30 } catch (ClassNotFoundException e) {
31 return clazz;
32 }
33 }
34
35 private Class[] getParameterTypes() {
36 int parameterCount = invocation.getParameterCount();
37 Class[] classes = new Class[parameterCount];
38 for (int i = 0; i < parameterCount; i++) {
39 classes[i] = invocation.getParameterType(i);
40 }
41 return classes;
42 }
43
44 public Object proceed() throws Throwable {
45 invocation.proceed();
46 return invocation.getResult();
47 }
48
49 public Object[] getArguments() {
50 int parameterCount = invocation.getParameterCount();
51 Object[] args = new Object[parameterCount];
52 for (int i = 0; i < parameterCount; i++) {
53 args[i] = invocation.getParameter(i);
54 }
55 return args;
56 }
57
58 public AccessibleObject getStaticPart() {
59 throw new UnsupportedOperationException();
60 }
61 }
5. Annotate component method and run.
written by Michael Kretinin