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 org.springframework.aop.SpringProxy;
020: import org.springframework.util.ClassUtils;
021:
022: /**
023: * Default {@link AopProxyFactory} implementation,
024: * creating either a CGLIB proxy or a JDK dynamic proxy.
025: *
026: * <p>Creates a CGLIB proxy if one the following is true
027: * for a given {@link AdvisedSupport} instance:
028: * <ul>
029: * <li>the "optimize" flag is set
030: * <li>the "proxyTargetClass" flag is set
031: * <li>no proxy interfaces have been specified
032: * </ul>
033: *
034: * <p>Note that the CGLIB library classes have to be present on
035: * the class path if an actual CGLIB proxy needs to be created.
036: *
037: * <p>In general, specify "proxyTargetClass" to enforce a CGLIB proxy,
038: * or specify one or more interfaces to use a JDK dynamic proxy.
039: *
040: * @author Rod Johnson
041: * @author Juergen Hoeller
042: * @since 12.03.2004
043: * @see AdvisedSupport#setOptimize
044: * @see AdvisedSupport#setProxyTargetClass
045: * @see AdvisedSupport#setInterfaces
046: */
047: public class DefaultAopProxyFactory implements AopProxyFactory {
048:
049: /** Whether the CGLIB2 library is present on the classpath */
050: private static final boolean cglibAvailable = ClassUtils.isPresent(
051: "net.sf.cglib.proxy.Enhancer", DefaultAopProxyFactory.class
052: .getClassLoader());
053:
054: public AopProxy createAopProxy(AdvisedSupport config)
055: throws AopConfigException {
056: if (config.isOptimize() || config.isProxyTargetClass()
057: || hasNoUserSuppliedProxyInterfaces(config)) {
058: Class targetClass = config.getTargetClass();
059: if (targetClass == null) {
060: throw new AopConfigException(
061: "TargetSource cannot determine target class: "
062: + "Either an interface or a target is required for proxy creation.");
063: }
064: if (targetClass.isInterface()) {
065: return new JdkDynamicAopProxy(config);
066: }
067: if (!cglibAvailable) {
068: throw new AopConfigException(
069: "Cannot proxy target class because CGLIB2 is not available. "
070: + "Add CGLIB to the class path or specify proxy interfaces.");
071: }
072: return CglibProxyFactory.createCglibProxy(config);
073: } else {
074: return new JdkDynamicAopProxy(config);
075: }
076: }
077:
078: /**
079: * Determine whether the supplied {@link AdvisedSupport} has only the
080: * {@link org.springframework.aop.SpringProxy} interface specified
081: * (or no proxy interfaces specified at all).
082: */
083: private boolean hasNoUserSuppliedProxyInterfaces(
084: AdvisedSupport config) {
085: Class[] interfaces = config.getProxiedInterfaces();
086: return (interfaces.length == 0 || (interfaces.length == 1 && SpringProxy.class
087: .equals(interfaces[0])));
088: }
089:
090: /**
091: * Inner factory class used to just introduce a CGLIB2 dependency
092: * when actually creating a CGLIB proxy.
093: */
094: private static class CglibProxyFactory {
095:
096: public static AopProxy createCglibProxy(
097: AdvisedSupport advisedSupport) {
098: return new Cglib2AopProxy(advisedSupport);
099: }
100: }
101:
102: }
|