Open Source Repository

Home /spring/spring-aop-3.0.5 | Repository Home


org/springframework/aop/framework/DefaultAopProxyFactory.java
/*
 * Copyright 2002-2007 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.aop.framework;

import java.io.Serializable;

import org.springframework.aop.SpringProxy;
import org.springframework.util.ClassUtils;

/**
 * Default {@link AopProxyFactory} implementation,
 * creating either a CGLIB proxy or a JDK dynamic proxy.
 *
 <p>Creates a CGLIB proxy if one the following is true
 * for a given {@link AdvisedSupport} instance:
 <ul>
 <li>the "optimize" flag is set
 <li>the "proxyTargetClass" flag is set
 <li>no proxy interfaces have been specified
 </ul>
 *
 <p>Note that the CGLIB library classes have to be present on
 * the class path if an actual CGLIB proxy needs to be created.
 *
 <p>In general, specify "proxyTargetClass" to enforce a CGLIB proxy,
 * or specify one or more interfaces to use a JDK dynamic proxy.
 *
 @author Rod Johnson
 @author Juergen Hoeller
 @since 12.03.2004
 @see AdvisedSupport#setOptimize
 @see AdvisedSupport#setProxyTargetClass
 @see AdvisedSupport#setInterfaces
 */
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

  /** Whether the CGLIB2 library is present on the classpath */
  private static final boolean cglibAvailable =
      ClassUtils.isPresent("net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class.getClassLoader());


  public AopProxy createAopProxy(AdvisedSupport configthrows AopConfigException {
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
      Class targetClass = config.getTargetClass();
      if (targetClass == null) {
        throw new AopConfigException("TargetSource cannot determine target class: " +
            "Either an interface or a target is required for proxy creation.");
      }
      if (targetClass.isInterface()) {
        return new JdkDynamicAopProxy(config);
      }
      if (!cglibAvailable) {
        throw new AopConfigException(
            "Cannot proxy target class because CGLIB2 is not available. " +
            "Add CGLIB to the class path or specify proxy interfaces.");
      }
      return CglibProxyFactory.createCglibProxy(config);
    }
    else {
      return new JdkDynamicAopProxy(config);
    }
  }

  /**
   * Determine whether the supplied {@link AdvisedSupport} has only the
   {@link org.springframework.aop.SpringProxy} interface specified
   * (or no proxy interfaces specified at all).
   */
  private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
    Class[] interfaces = config.getProxiedInterfaces();
    return (interfaces.length == || (interfaces.length == && SpringProxy.class.equals(interfaces[0])));
  }


  /**
   * Inner factory class used to just introduce a CGLIB2 dependency
   * when actually creating a CGLIB proxy.
   */
  private static class CglibProxyFactory {

    public static AopProxy createCglibProxy(AdvisedSupport advisedSupport) {
      return new Cglib2AopProxy(advisedSupport);
    }
  }

}