1. /*
  2. * Copyright 2002-2004 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. package org.springframework.aop.framework;
  17. import org.apache.commons.logging.Log;
  18. import org.apache.commons.logging.LogFactory;
  19. /**
  20. * Convenience superclass for configuration used in creating proxies,
  21. * to ensure that all proxy creators have consistent properties.
  22. *
  23. * <p>Note that it is no longer possible to configure subclasses to expose
  24. * the MethodInvocation. Interceptors should normally manage their own
  25. * ThreadLocals if they need to make resources available to advised objects.
  26. * If it's absolutely necessary to expose the MethodInvocation, use an
  27. * interceptor to do so.
  28. *
  29. * @author Rod Johnson
  30. * @version $Id: ProxyConfig.java,v 1.11 2004/05/27 09:14:40 jhoeller Exp $
  31. */
  32. public class ProxyConfig {
  33. /*
  34. * Note that some of the instance variables in this class and AdvisedSupport
  35. * are protected, rather than private, as is usually preferred in Spring
  36. * (following "Expert One-on-One J2EE Design and Development", Chapter 4).
  37. * This allows direct field access in the AopProxy implementations, which
  38. * produces a 10-20% reduction in AOP performance overhead compared with
  39. * method access. - RJ, December 10, 2003.
  40. */
  41. protected final Log logger = LogFactory.getLog(getClass());
  42. private boolean proxyTargetClass;
  43. private boolean optimize;
  44. /**
  45. * Should proxies obtained from this configuration expose
  46. * the AOP proxy for the AopContext class to retrieve for targets?
  47. * The default is false, as enabling this property may impair performance.
  48. */
  49. protected boolean exposeProxy;
  50. /**
  51. * Is this config frozen: that is, should it be impossible
  52. * to change advice. Default is not frozen.
  53. */
  54. private boolean frozen;
  55. /** Factory used to create AopProxy instances */
  56. private AopProxyFactory aopProxyFactory = new DefaultAopProxyFactory();
  57. /**
  58. * Set whether to proxy the target class directly as well as any interfaces.
  59. * We can set this to true to force CGLIB proxying. Default is false.
  60. */
  61. public void setProxyTargetClass(boolean proxyTargetClass) {
  62. this.proxyTargetClass = proxyTargetClass;
  63. }
  64. /**
  65. * Return whether to proxy the target class directly as well as any interfaces.
  66. */
  67. public boolean getProxyTargetClass() {
  68. return this.proxyTargetClass;
  69. }
  70. /**
  71. * Set whether proxies should perform agressive optimizations.
  72. * The exact meaning of "agressive optimizations" will differ
  73. * between proxies, but there is usually some tradeoff.
  74. * <p>For example, optimization will usually mean that advice changes won't
  75. * take effect after a proxy has been created. For this reason, optimization
  76. * is disabled by default. An optimize value of true may be ignored
  77. * if other settings preclude optimization: for example, if exposeProxy
  78. * is set to true and that's not compatible with the optimization.
  79. * <p>For example, CGLIB-enhanced proxies may optimize out.
  80. * overriding methods with no advice chain. This can produce 2.5x
  81. * performance improvement for methods with no advice.
  82. * <p><b>Warning:</b> Setting this to true can produce large performance
  83. * gains when using CGLIB (also set proxyTargetClass to true), so it's
  84. * a good setting for performance-critical proxies. However, enabling this
  85. * will mean that advice cannot be changed after a proxy has been obtained
  86. * from this factory.
  87. * @param optimize whether to enable agressive optimizations.
  88. * Default is false.
  89. */
  90. public void setOptimize(boolean optimize) {
  91. this.optimize = optimize;
  92. }
  93. /**
  94. * Return whether proxies should perform agressive optimizations.
  95. */
  96. public boolean getOptimize() {
  97. return this.optimize;
  98. }
  99. /**
  100. * Set whether the proxy should be exposed by the AOP framework as a
  101. * ThreadLocal for retrieval via the AopContext class. This is useful
  102. * if an advised object needs to call another advised method on itself.
  103. * (If it uses <code>this</code>, the invocation will not be advised).
  104. * <p>Default is false, for optimal performance.
  105. */
  106. public void setExposeProxy(boolean exposeProxy) {
  107. this.exposeProxy = exposeProxy;
  108. }
  109. /**
  110. * Return whether the AOP proxy will expose the AOP proxy for
  111. * each invocation.
  112. */
  113. public boolean getExposeProxy() {
  114. return this.exposeProxy;
  115. }
  116. /**
  117. * Set whether this config should be frozen.
  118. * <p>When a config is frozen, no advice changes can be made. This is
  119. * useful for optimization, and useful when we don't want callers to
  120. * be able to manipulate configuration after casting to Advised.
  121. */
  122. public void setFrozen(boolean frozen) {
  123. this.frozen = frozen;
  124. }
  125. /**
  126. * Return whether the config is frozen, and no advice changes can be made.
  127. */
  128. public boolean isFrozen() {
  129. return frozen;
  130. }
  131. /**
  132. * Customize the AopProxyFactory, allowing different strategies
  133. * to be dropped in without changing the core framework.
  134. * Default is DefaultAopProxyFactory, using dynamic proxies or CGLIB.
  135. * <p>For example, an AopProxyFactory could return an AopProxy using
  136. * dynamic proxies, CGLIB or code generation strategy.
  137. */
  138. public void setAopProxyFactory(AopProxyFactory apf) {
  139. this.aopProxyFactory = apf;
  140. }
  141. /**
  142. * Return the AopProxyFactory that this ProxyConfig uses.
  143. */
  144. public AopProxyFactory getAopProxyFactory() {
  145. return this.aopProxyFactory;
  146. }
  147. /**
  148. * Copy configuration from the other config object.
  149. * @param other object to copy configuration from
  150. */
  151. public void copyFrom(ProxyConfig other) {
  152. this.proxyTargetClass = other.proxyTargetClass;
  153. this.optimize = other.getOptimize();
  154. this.exposeProxy = other.exposeProxy;
  155. this.frozen = other.frozen;
  156. this.aopProxyFactory = other.aopProxyFactory;
  157. }
  158. public String toString() {
  159. StringBuffer sb = new StringBuffer();
  160. sb.append("proxyTargetClass=" + this.proxyTargetClass + "; ");
  161. sb.append("optimize=" + this.optimize + "; ");
  162. sb.append("exposeProxy=" + this.exposeProxy + "; ");
  163. sb.append("frozen=" + this.frozen + "; ");
  164. sb.append("aopProxyFactory=" + this.aopProxyFactory + "; ");
  165. return sb.toString();
  166. }
  167. }