动态代理两种方式
参考https://www.cnblogs.com/leifei/p/8263448.html
- JDK动态代理
- Cglib动态代理
JDK
UserManager
package org.neosoft.proxy;
public interface IUserService {
void sayHello(String userName);
}
UserManagerImpl
package org.neosoft.proxy;
public class UserServiceImpl implements IUserService {
@Override
public void sayHello(String userName) {
System.out.println("Hello:" + userName);
}
}
JdkProxy
package org.neosoft.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class JdkProxy implements InvocationHandler {
/**
* 需要代理的目标对象
*/
private Object target;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK动态代理,监听开始!");
Object result = method.invoke(target, args);
System.out.println("JDK动态代理,监听结束!");
return result;
}
/**
* 定义获取代理对象方法
*
* @param targetObject
* @return
*/
public Object getJDKProxy(Object targetObject) {
//为目标对象target赋值
this.target = targetObject;
//JDK动态代理只能针对实现了接口的类进行代理,newProxyInstance 函数所需参数就可看出
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
}
JdkProxyTest
package org.neosoft.proxy;
import java.io.IOException;
public class JdkProxyTest {
public static void main(String[] args) throws IOException {
// 根目录下输出代理生成的类
// 不同的JDK版本参数可能不一致,直接查看源码ProxyGenerator.saveGeneratedFiles即可
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
//实例化JDKProxy对象
JdkProxy jdkProxy = new JdkProxy();
//获取代理对象
IUserService user = (IUserService) jdkProxy.getJDKProxy(new UserServiceImpl());
//执行方法
user.sayHello("jdk");
}
}
运行后产生$Proxy0
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.sun.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
import org.neosoft.proxy.IUserService;
public final class $Proxy0 extends Proxy implements IUserService {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public $Proxy0(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void sayHello(String var1) throws {
try {
super.h.invoke(this, m3, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("org.neosoft.proxy.IUserService").getMethod("sayHello", Class.forName("java.lang.String"));
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
Cglib
package org.neosoft.proxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* @description
* @author: zhusy
* @date:2021/7/16
**/
public class CglibProxy implements MethodInterceptor {
/**
* 需要代理的目标对象
*/
private Object target;
/**
* 重写拦截方法
* @param obj
* @param method
* @param arr
* @param proxy
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] arr, MethodProxy proxy) throws Throwable {
System.out.println("Cglib动态代理,监听开始!");
//方法执行,参数:target 目标对象 arr参数数组
Object invoke = method.invoke(target, arr);
System.out.println("Cglib动态代理,监听结束!");
return invoke;
}
/**
* 定义获取代理对象方法
* @param objectTarget
* @return
*/
public Object getCglibProxy(Object objectTarget){
//为目标对象target赋值
this.target = objectTarget;
Enhancer enhancer = new Enhancer();
//设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类
enhancer.setSuperclass(objectTarget.getClass());
// 设置回调
enhancer.setCallback(this);
//创建并返回代理对象
Object result = enhancer.create();
return result;
}
}
CglibProxyTest
package org.neosoft.proxy;
import org.springframework.cglib.core.DebuggingClassWriter;
/**
* @description
* @author: zhusy
* @date:2021/7/16
**/
public class CglibProxyTest {
public static void main(String[] args) {
// 生成的代理类输出到文件
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "C:\\class");
//实例化CglibProxy对象
CglibProxy cglib = new CglibProxy();
//获取代理对象
IUserService user = (IUserService) cglib.getCglibProxy(new UserServiceImpl());
//执行方法
user.sayHello("cglib");
}
}
UserManagerImpl$ EnhancerByCGLIB$$87eb3d37
package org.neosoft.proxy;
import java.lang.reflect.Method;
import org.springframework.cglib.core.ReflectUtils;
import org.springframework.cglib.core.Signature;
import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Factory;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
public class UserManagerImpl$$EnhancerByCGLIB$$87eb3d37 extends UserManagerImpl implements Factory {
private boolean CGLIB$BOUND;
public static Object CGLIB$FACTORY_DATA;
private static final ThreadLocal CGLIB$THREAD_CALLBACKS;
private static final Callback[] CGLIB$STATIC_CALLBACKS;
private MethodInterceptor CGLIB$CALLBACK_0;
private static Object CGLIB$CALLBACK_FILTER;
private static final Method CGLIB$addUser$0$Method;
private static final MethodProxy CGLIB$addUser$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$delUser$1$Method;
private static final MethodProxy CGLIB$delUser$1$Proxy;
private static final Method CGLIB$equals$2$Method;
private static final MethodProxy CGLIB$equals$2$Proxy;
private static final Method CGLIB$toString$3$Method;
private static final MethodProxy CGLIB$toString$3$Proxy;
private static final Method CGLIB$hashCode$4$Method;
private static final MethodProxy CGLIB$hashCode$4$Proxy;
private static final Method CGLIB$clone$5$Method;
private static final MethodProxy CGLIB$clone$5$Proxy;
static void CGLIB$STATICHOOK1() {
CGLIB$THREAD_CALLBACKS = new ThreadLocal();
CGLIB$emptyArgs = new Object[0];
Class clazz1 = Class.forName("org.neosoft.proxy.UserManagerImpl$$EnhancerByCGLIB$$87eb3d37");
Class clazz2;
CGLIB$equals$2$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[0];
CGLIB$equals$2$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
CGLIB$toString$3$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[1];
CGLIB$toString$3$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
CGLIB$hashCode$4$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[2];
CGLIB$hashCode$4$Proxy = MethodProxy.create(clazz2, clazz1, "()I", "hashCode", "CGLIB$hashCode$4");
CGLIB$clone$5$Method = ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods())[3];
CGLIB$clone$5$Proxy = MethodProxy.create(clazz2, clazz1, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
ReflectUtils.findMethods(new String[] { "equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;" }, (clazz2 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$addUser$0$Method = ReflectUtils.findMethods(new String[] { "addUser", "(Ljava/lang/String;Ljava/lang/String;)V", "delUser", "(Ljava/lang/String;)V" }, (clazz2 = Class.forName("org.neosoft.proxy.UserManagerImpl")).getDeclaredMethods())[0];
CGLIB$addUser$0$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/String;Ljava/lang/String;)V", "addUser", "CGLIB$addUser$0");
CGLIB$delUser$1$Method = ReflectUtils.findMethods(new String[] { "addUser", "(Ljava/lang/String;Ljava/lang/String;)V", "delUser", "(Ljava/lang/String;)V" }, (clazz2 = Class.forName("org.neosoft.proxy.UserManagerImpl")).getDeclaredMethods())[1];
CGLIB$delUser$1$Proxy = MethodProxy.create(clazz2, clazz1, "(Ljava/lang/String;)V", "delUser", "CGLIB$delUser$1");
ReflectUtils.findMethods(new String[] { "addUser", "(Ljava/lang/String;Ljava/lang/String;)V", "delUser", "(Ljava/lang/String;)V" }, (clazz2 = Class.forName("org.neosoft.proxy.UserManagerImpl")).getDeclaredMethods());
}
final void CGLIB$addUser$0(String paramString1, String paramString2) { super.addUser(paramString1, paramString2); }
public final void addUser(String paramString1, String paramString2) {
if (this.CGLIB$CALLBACK_0 == null) {
this.CGLIB$CALLBACK_0;
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
new Object[2][0] = paramString1;
new Object[2][1] = paramString2;
return;
}
super.addUser(paramString1, paramString2);
}
final void CGLIB$delUser$1(String paramString) { super.delUser(paramString); }
public final void delUser(String paramString) {
if (this.CGLIB$CALLBACK_0 == null) {
this.CGLIB$CALLBACK_0;
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
new Object[1][0] = paramString;
return;
}
super.delUser(paramString);
}
final boolean CGLIB$equals$2(Object paramObject) { return super.equals(paramObject); }
public final boolean equals(Object paramObject) {
if (this.CGLIB$CALLBACK_0 == null) {
this.CGLIB$CALLBACK_0;
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy);
return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy) == null) ? false : ((Boolean)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$equals$2$Method, new Object[] { paramObject }, CGLIB$equals$2$Proxy)).booleanValue();
}
return super.equals(paramObject);
}
final String CGLIB$toString$3() { return super.toString(); }
public final String toString() {
if (this.CGLIB$CALLBACK_0 == null) {
this.CGLIB$CALLBACK_0;
CGLIB$BIND_CALLBACKS(this);
}
return (this.CGLIB$CALLBACK_0 != null) ? (String)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$toString$3$Method, CGLIB$emptyArgs, CGLIB$toString$3$Proxy) : super.toString();
}
final int CGLIB$hashCode$4() { return super.hashCode(); }
public final int hashCode() {
if (this.CGLIB$CALLBACK_0 == null) {
this.CGLIB$CALLBACK_0;
CGLIB$BIND_CALLBACKS(this);
}
if (this.CGLIB$CALLBACK_0 != null) {
this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
return (this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy) == null) ? 0 : ((Number)this.CGLIB$CALLBACK_0.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy)).intValue();
}
return super.hashCode();
}
final Object CGLIB$clone$5() throws CloneNotSupportedException { return super.clone(); }
protected final Object clone() throws CloneNotSupportedException {
if (this.CGLIB$CALLBACK_0 == null) {
this.CGLIB$CALLBACK_0;
CGLIB$BIND_CALLBACKS(this);
}
return (this.CGLIB$CALLBACK_0 != null) ? this.CGLIB$CALLBACK_0.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(Signature paramSignature) { // Byte code:
// 0: aload_0
// 1: invokevirtual toString : ()Ljava/lang/String;
// 4: dup
// 5: invokevirtual hashCode : ()I
// 8: lookupswitch default -> 140, -508378822 -> 68, 1728090441 -> 80, 1826985398 -> 92, 1913648695 -> 104, 1917756541 -> 116, 1984935277 -> 128
// 68: ldc 'clone()Ljava/lang/Object;'
// 70: invokevirtual equals : (Ljava/lang/Object;)Z
// 73: ifeq -> 141
// 76: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$clone$5$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
// 79: areturn
// 80: ldc 'delUser(Ljava/lang/String;)V'
// 82: invokevirtual equals : (Ljava/lang/Object;)Z
// 85: ifeq -> 141
// 88: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$delUser$1$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
// 91: areturn
// 92: ldc 'equals(Ljava/lang/Object;)Z'
// 94: invokevirtual equals : (Ljava/lang/Object;)Z
// 97: ifeq -> 141
// 100: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$equals$2$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
// 103: areturn
// 104: ldc 'toString()Ljava/lang/String;'
// 106: invokevirtual equals : (Ljava/lang/Object;)Z
// 109: ifeq -> 141
// 112: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$toString$3$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
// 115: areturn
// 116: ldc 'addUser(Ljava/lang/String;Ljava/lang/String;)V'
// 118: invokevirtual equals : (Ljava/lang/Object;)Z
// 121: ifeq -> 141
// 124: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$addUser$0$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
// 127: areturn
// 128: ldc 'hashCode()I'
// 130: invokevirtual equals : (Ljava/lang/Object;)Z
// 133: ifeq -> 141
// 136: getstatic org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$hashCode$4$Proxy : Lorg/springframework/cglib/proxy/MethodProxy;
// 139: areturn
// 140: pop
// 141: aconst_null
// 142: areturn }
public UserManagerImpl$$EnhancerByCGLIB$$87eb3d37() { CGLIB$BIND_CALLBACKS(this); }
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$THREAD_CALLBACKS.set(paramArrayOfCallback); }
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] paramArrayOfCallback) { CGLIB$STATIC_CALLBACKS = paramArrayOfCallback; }
private static final void CGLIB$BIND_CALLBACKS(Object paramObject) {
UserManagerImpl$$EnhancerByCGLIB$$87eb3d37 userManagerImpl$$EnhancerByCGLIB$$87eb3d37 = (UserManagerImpl$$EnhancerByCGLIB$$87eb3d37)paramObject;
if (!userManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$BOUND) {
userManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$BOUND = true;
if (CGLIB$THREAD_CALLBACKS.get() == null) {
CGLIB$THREAD_CALLBACKS.get();
if (CGLIB$STATIC_CALLBACKS == null) {
CGLIB$STATIC_CALLBACKS;
return;
}
}
userManagerImpl$$EnhancerByCGLIB$$87eb3d37.CGLIB$CALLBACK_0 = (MethodInterceptor)(Callback[])CGLIB$THREAD_CALLBACKS.get()[0];
}
}
public Object newInstance(Callback[] paramArrayOfCallback) {
CGLIB$SET_THREAD_CALLBACKS(paramArrayOfCallback);
CGLIB$SET_THREAD_CALLBACKS(null);
return new UserManagerImpl$$EnhancerByCGLIB$$87eb3d37();
}
public Object newInstance(Callback paramCallback) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[] { paramCallback });
CGLIB$SET_THREAD_CALLBACKS(null);
return new UserManagerImpl$$EnhancerByCGLIB$$87eb3d37();
}
public Object newInstance(Class[] paramArrayOfClass, Object[] paramArrayOfObject, Callback[] paramArrayOfCallback) { // Byte code:
// 0: aload_3
// 1: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
// 4: new org/neosoft/proxy/UserManagerImpl$$EnhancerByCGLIB$$87eb3d37
// 7: dup
// 8: aload_1
// 9: dup
// 10: arraylength
// 11: tableswitch default -> 35, 0 -> 28
// 28: pop
// 29: invokespecial <init> : ()V
// 32: goto -> 49
// 35: goto -> 38
// 38: pop
// 39: new java/lang/IllegalArgumentException
// 42: dup
// 43: ldc 'Constructor not found'
// 45: invokespecial <init> : (Ljava/lang/String;)V
// 48: athrow
// 49: aconst_null
// 50: invokestatic CGLIB$SET_THREAD_CALLBACKS : ([Lorg/springframework/cglib/proxy/Callback;)V
// 53: areturn }
public Callback getCallback(int paramInt) {
CGLIB$BIND_CALLBACKS(this);
switch (paramInt) {
case 0:
}
this.CGLIB$CALLBACK_0;
return null;
}
public void setCallback(int paramInt, Callback paramCallback) {
switch (paramInt) {
case 0:
this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramCallback;
break;
}
}
public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[] { this.CGLIB$CALLBACK_0 };
}
public void setCallbacks(Callback[] paramArrayOfCallback) { this.CGLIB$CALLBACK_0 = (MethodInterceptor)paramArrayOfCallback[0]; }
static {
CGLIB$STATICHOOK1();
}
}
SpringAOP动态代理
接着https://www.jianshu.com/p/92e09c466176
initializeBean之后进入
AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
AbstractAutoProxyCreator#postProcessAfterInitialization
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
// 获取增强器
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
AbstractAutoProxyCreator#wrapIfNecessary
创建代理类
AbstractAutoProxyCreator#createProxy
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 生成动态代理对象
return proxyFactory.getProxy(classLoader);
}
ProxyFactory#getProxy(java.lang.ClassLoader)
ProxyCreatorSupport#createAopProxy
DefaultAopProxyFactory#createAopProxy
选择JdkDynamicAopProxy还是ObjenesisCglibAopProxy代理
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws 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() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
CglibAopProxy#getProxy(java.lang.ClassLoader)
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating CGLIB proxy: " + this.advised.getTargetSource());
}
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
catch (CodeGenerationException | IllegalArgumentException ex) {
throw new AopConfigException("Could not generate CGLIB subclass of " + this.advised.getTargetClass() +
": Common causes of this problem include using a final class or a non-visible class",
ex);
}
catch (Throwable ex) {
// TargetSource.getTarget() failed
throw new AopConfigException("Unexpected AOP exception", ex);
}
}
ObjenesisCglibAopProxy#createProxyClassAndInstance
@Override
protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
Class<?> proxyClass = enhancer.createClass();
Object proxyInstance = null;
if (objenesis.isWorthTrying()) {
try {
proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
}
catch (Throwable ex) {
logger.debug("Unable to instantiate proxy using Objenesis, " +
"falling back to regular proxy construction", ex);
}
}
if (proxyInstance == null) {
// Regular instantiation via default constructor...
try {
Constructor<?> ctor = (this.constructorArgs != null ?
proxyClass.getDeclaredConstructor(this.constructorArgTypes) :
proxyClass.getDeclaredConstructor());
ReflectionUtils.makeAccessible(ctor);
proxyInstance = (this.constructorArgs != null ?
ctor.newInstance(this.constructorArgs) : ctor.newInstance());
}
catch (Throwable ex) {
throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +
"and regular proxy instantiation via default constructor fails as well", ex);
}
}
((Factory) proxyInstance).setCallbacks(callbacks);
return proxyInstance;
}
对比上面的测试代码,也是enhancer.create(),保持一致。
// cglibProxy
public Object getCglibProxy(Object objectTarget){
//为目标对象target赋值
this.target = objectTarget;
Enhancer enhancer = new Enhancer();
//设置父类,因为Cglib是针对指定的类生成一个子类,所以需要指定父类
enhancer.setSuperclass(objectTarget.getClass());
// 设置回调
enhancer.setCallback(this);
//创建并返回代理对象
Object result = enhancer.create();
return result;
}
//jdkProxy
public Object getJDKProxy(Object targetObject) {
//为目标对象target赋值
this.target = targetObject;
//JDK动态代理只能针对实现了接口的类进行代理,newProxyInstance 函数所需参数就可看出
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
下面看JDK
JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
与上面的测试代码也一致Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
return Proxy.newProxyInstance(classLoader, this.proxiedInterfaces, this);
}
核心类图:
创建的流程图