001/* 002 * Copyright 2002-2016 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 * https://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 017package org.springframework.aop.framework; 018 019import org.aopalliance.intercept.Interceptor; 020 021import org.springframework.aop.TargetSource; 022import org.springframework.util.ClassUtils; 023 024/** 025 * Factory for AOP proxies for programmatic use, rather than via declarative 026 * setup in a bean factory. This class provides a simple way of obtaining 027 * and configuring AOP proxy instances in custom user code. 028 * 029 * @author Rod Johnson 030 * @author Juergen Hoeller 031 * @author Rob Harrop 032 * @since 14.03.2003 033 */ 034@SuppressWarnings("serial") 035public class ProxyFactory extends ProxyCreatorSupport { 036 037 /** 038 * Create a new ProxyFactory. 039 */ 040 public ProxyFactory() { 041 } 042 043 /** 044 * Create a new ProxyFactory. 045 * <p>Will proxy all interfaces that the given target implements. 046 * @param target the target object to be proxied 047 */ 048 public ProxyFactory(Object target) { 049 setTarget(target); 050 setInterfaces(ClassUtils.getAllInterfaces(target)); 051 } 052 053 /** 054 * Create a new ProxyFactory. 055 * <p>No target, only interfaces. Must add interceptors. 056 * @param proxyInterfaces the interfaces that the proxy should implement 057 */ 058 public ProxyFactory(Class<?>... proxyInterfaces) { 059 setInterfaces(proxyInterfaces); 060 } 061 062 /** 063 * Create a new ProxyFactory for the given interface and interceptor. 064 * <p>Convenience method for creating a proxy for a single interceptor, 065 * assuming that the interceptor handles all calls itself rather than 066 * delegating to a target, like in the case of remoting proxies. 067 * @param proxyInterface the interface that the proxy should implement 068 * @param interceptor the interceptor that the proxy should invoke 069 */ 070 public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) { 071 addInterface(proxyInterface); 072 addAdvice(interceptor); 073 } 074 075 /** 076 * Create a ProxyFactory for the specified {@code TargetSource}, 077 * making the proxy implement the specified interface. 078 * @param proxyInterface the interface that the proxy should implement 079 * @param targetSource the TargetSource that the proxy should invoke 080 */ 081 public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) { 082 addInterface(proxyInterface); 083 setTargetSource(targetSource); 084 } 085 086 087 /** 088 * Create a new proxy according to the settings in this factory. 089 * <p>Can be called repeatedly. Effect will vary if we've added 090 * or removed interfaces. Can add and remove interceptors. 091 * <p>Uses a default class loader: Usually, the thread context class loader 092 * (if necessary for proxy creation). 093 * @return the proxy object 094 */ 095 public Object getProxy() { 096 return createAopProxy().getProxy(); 097 } 098 099 /** 100 * Create a new proxy according to the settings in this factory. 101 * <p>Can be called repeatedly. Effect will vary if we've added 102 * or removed interfaces. Can add and remove interceptors. 103 * <p>Uses the given class loader (if necessary for proxy creation). 104 * @param classLoader the class loader to create the proxy with 105 * (or {@code null} for the low-level proxy facility's default) 106 * @return the proxy object 107 */ 108 public Object getProxy(ClassLoader classLoader) { 109 return createAopProxy().getProxy(classLoader); 110 } 111 112 113 /** 114 * Create a new proxy for the given interface and interceptor. 115 * <p>Convenience method for creating a proxy for a single interceptor, 116 * assuming that the interceptor handles all calls itself rather than 117 * delegating to a target, like in the case of remoting proxies. 118 * @param proxyInterface the interface that the proxy should implement 119 * @param interceptor the interceptor that the proxy should invoke 120 * @return the proxy object 121 * @see #ProxyFactory(Class, org.aopalliance.intercept.Interceptor) 122 */ 123 @SuppressWarnings("unchecked") 124 public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) { 125 return (T) new ProxyFactory(proxyInterface, interceptor).getProxy(); 126 } 127 128 /** 129 * Create a proxy for the specified {@code TargetSource}, 130 * implementing the specified interface. 131 * @param proxyInterface the interface that the proxy should implement 132 * @param targetSource the TargetSource that the proxy should invoke 133 * @return the proxy object 134 * @see #ProxyFactory(Class, org.springframework.aop.TargetSource) 135 */ 136 @SuppressWarnings("unchecked") 137 public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) { 138 return (T) new ProxyFactory(proxyInterface, targetSource).getProxy(); 139 } 140 141 /** 142 * Create a proxy for the specified {@code TargetSource} that extends 143 * the target class of the {@code TargetSource}. 144 * @param targetSource the TargetSource that the proxy should invoke 145 * @return the proxy object 146 */ 147 public static Object getProxy(TargetSource targetSource) { 148 if (targetSource.getTargetClass() == null) { 149 throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class"); 150 } 151 ProxyFactory proxyFactory = new ProxyFactory(); 152 proxyFactory.setTargetSource(targetSource); 153 proxyFactory.setProxyTargetClass(true); 154 return proxyFactory.getProxy(); 155 } 156 157}