001: /*
002: * Copyright 2002-2007 the original author or authors.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: */
016:
017: package org.springframework.aop.framework;
018:
019: import java.io.Serializable;
020:
021: import org.springframework.aop.SpringProxy;
022: import org.springframework.util.ClassUtils;
023:
024: /**
025: * Default {@link AopProxyFactory} implementation,
026: * creating either a CGLIB proxy or a JDK dynamic proxy.
027: *
028: * <p>Creates a CGLIB proxy if one the following is true
029: * for a given {@link AdvisedSupport} instance:
030: * <ul>
031: * <li>the "optimize" flag is set
032: * <li>the "proxyTargetClass" flag is set
033: * <li>no proxy interfaces have been specified
034: * </ul>
035: *
036: * <p>Note that the CGLIB library classes have to be present on
037: * the class path if an actual CGLIB proxy needs to be created.
038: *
039: * <p>In general, specify "proxyTargetClass" to enforce a CGLIB proxy,
040: * or specify one or more interfaces to use a JDK dynamic proxy.
041: *
042: * @author Rod Johnson
043: * @author Juergen Hoeller
044: * @since 12.03.2004
045: * @see AdvisedSupport#setOptimize
046: * @see AdvisedSupport#setProxyTargetClass
047: * @see AdvisedSupport#setInterfaces
048: */
049: public class DefaultAopProxyFactory implements AopProxyFactory,
050: Serializable {
051:
052: /** Whether the CGLIB2 library is present on the classpath */
053: private static final boolean cglibAvailable = ClassUtils.isPresent(
054: "net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class
055: .getClassLoader());
056:
057: public AopProxy createAopProxy(AdvisedSupport config)
058: throws AopConfigException {
059: if (config.isOptimize() || config.isProxyTargetClass()
060: || hasNoUserSuppliedProxyInterfaces(config)) {
061: Class targetClass = config.getTargetClass();
062: if (targetClass == null) {
063: throw new AopConfigException(
064: "TargetSource cannot determine target class: "
065: + "Either an interface or a target is required for proxy creation.");
066: }
067: if (targetClass.isInterface()) {
068: return new JdkDynamicAopProxy(config);
069: }
070: if (!cglibAvailable) {
071: throw new AopConfigException(
072: "Cannot proxy target class because CGLIB2 is not available. "
073: + "Add CGLIB to the class path or specify proxy interfaces.");
074: }
075: return CglibProxyFactory.createCglibProxy(config);
076: } else {
077: return new JdkDynamicAopProxy(config);
078: }
079: }
080:
081: /**
082: * Determine whether the supplied {@link AdvisedSupport} has only the
083: * {@link org.springframework.aop.SpringProxy} interface specified
084: * (or no proxy interfaces specified at all).
085: */
086: private boolean hasNoUserSuppliedProxyInterfaces(
087: AdvisedSupport config) {
088: Class[] interfaces = config.getProxiedInterfaces();
089: return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class
090: .equals(interfaces[0])));
091: }
092:
093: /**
094: * Inner factory class used to just introduce a CGLIB2 dependency
095: * when actually creating a CGLIB proxy.
096: */
097: private static class CglibProxyFactory {
098:
099: public static AopProxy createCglibProxy(
100: AdvisedSupport advisedSupport) {
101: return new Cglib2AopProxy(advisedSupport);
102: }
103: }
104:
105: }
|