01: /*
02: * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
03: */
04: package com.tcspring;
05:
06: import org.apache.commons.logging.Log;
07: import org.apache.commons.logging.LogFactory;
08: import org.springframework.aop.framework.AdvisedSupport;
09: import org.springframework.aop.framework.ProxyFactory;
10: import org.springframework.aop.framework.ProxyFactoryBean;
11: import org.springframework.beans.factory.BeanFactory;
12:
13: import com.tc.aspectwerkz.joinpoint.StaticJoinPoint;
14:
15: /**
16: * Intercepts the Spring AOP proxy creation and returns a FastProxy instead - falls back to regular creation upon failure
17: * or if some requirements are not fulfilled.
18: *
19: * @author Jonas Bonér
20: */
21: public class AopProxyFactoryProtocol {
22: private final transient Log logger = LogFactory.getLog(getClass());
23:
24: /**
25: * Around advice that is intercepting the pointcut:
26: * <tt>
27: * execution(* org.springframework.aop.framework.AopProxyFactory+.createAopProxy(..)) && args(proxyFactory)
28: * </tt>
29: */
30: public Object createAopProxy(StaticJoinPoint jp,
31: AdvisedSupport proxyFactory) throws Throwable {
32: ApplicationHelper applicationHelper = new ApplicationHelper(
33: proxyFactory.getClass());
34: if (!applicationHelper.isDSOApplication()
35: || !applicationHelper.isFastProxyEnabled()) {
36: return jp.proceed();
37: }
38:
39: try {
40: if (proxyFactory instanceof ProxyFactoryBean) {
41: return new FastAopProxy((ProxyFactoryBean) proxyFactory);
42: } else if (proxyFactory instanceof ProxyFactory
43: && proxyFactory.isFrozen()) {
44: return jp.proceed(); // TODO implement support for ProxyFactory later if needed
45: } else {
46: return jp.proceed();
47: }
48: } catch (Throwable e) {
49: logger
50: .warn("Falling back to using regular Spring AOP proxy creation, due to: "
51: + e);
52: // if something goes wrong fall back on using cglib or dynamic proxy
53: // f.e. mixins are not supported so -> exception -> fallback to cglib
54: return jp.proceed();
55: }
56: }
57:
58: /**
59: * Advises PCD: before(execution(void saveBeanFactory(..)) && args(beanFactory) && this(bean))
60: */
61: public void saveBeanFactory(BeanFactoryAware bean,
62: BeanFactory beanFactory) throws Throwable {
63: bean.tc$setBeanFactory(beanFactory);
64: }
65:
66: /**
67: * Mixin to hold a publicly accessible reference to BeanFactory that created the bean
68: */
69: public static class BeanFactoryAwareMixin implements
70: BeanFactoryAware {
71: private transient BeanFactory beanFactory;
72:
73: public void tc$setBeanFactory(BeanFactory beanFactory) {
74: this .beanFactory = beanFactory;
75: }
76:
77: public BeanFactory tc$getBeanFactory() {
78: return beanFactory;
79: }
80: }
81:
82: }
|