概述
- 代理模式(proxy pattern):是23种设计模式的一种,属于结构性的模式。指一个对象本身不做实际的操作,而是通过其他对象来得到自己想要的结果。
- 意义:目标对象只需要关心自己的实现细节,通过代理对象来实现功能的增强,可以扩展目标对象的功能。
- 体现了非常重要的编程思想:不能随便修改源码,如果需要修改源码,通过修改代理的方式来扩展功能的扩展。
代理的实现方式
-
Java中代理图示
-
元素组成
- 接口:定义行为和规范的
- 被代理类,是目标对象
- 代理类
静态代理
案例
-
通过代理模式实现事务操作
-
创建domain对象
/**
* @Author sima
* @Date 2023/4/25 18:01
*/
@Data
public class Student {
private String name;
private int age;
}
- 创建service接口定义规范
/**
* @Author sima
* @Date 2023/4/25 18:00
*/
public interface IStudentService {
/**
* 添加学生
*/
void save();
/**
* 查询学生信息
* @param id
* @return
*/
Student query(Long id);
}
- 创建实现类(被代理类)
/**
* @Author sima
* @Date 2023/4/25 18:05
*/
public class StudentServiceImpl implements IStudentService {
@Override
public void save() {
System.out.println("保存学生信息");
}
@Override
public Student query(Long id) {
Student student = new Student();
student.setName("张三");
student.setAge(18);
return student;
}
}
- 创建事务类对象
/**
* @Author sima
* @Date 2023/4/25 18:10
*/
public class DaoTransaction {
public void before() {
System.out.println("开启事务");
}
public void after() {
System.out.println("关闭事务");
}
}
- 创建代理类对象
/**
* @Author sima
* @Date 2023/4/25 18:12
*/
public class ProxyStudent implements IStudentService {
//目标对象
private StudentServiceImpl studentService;
//需要做的增强对象
private DaoTransaction transaction;
/**
* 通过构造器获取目标类和增强类对象
* @param studentService
* @param transaction
*/
public ProxyStudent(StudentServiceImpl studentService,DaoTransaction transaction){
this.studentService = studentService;
this.transaction = transaction;
}
@Override
public void save() {
//开启事务操作
transaction.before();
//目标类的操作
studentService.save();
//关闭事务操作
transaction.after();
}
@Override
public Student query(Long id) {
studentService.query(id);
}
}
- 测试方法
import org.junit.Test;
/**
* @Author sima
* @Date 2023/4/25 18:19
*/
public class TestStudent {
/**
* 保存学生信息
*/
@Test
public void testSave(){
DaoTransaction daoTransaction = new DaoTransaction();
StudentServiceImpl studentService = new StudentServiceImpl();
ProxyStudent proxyStudent = new ProxyStudent(studentService, daoTransaction);
proxyStudent.save();
// 开启事务
// 保存学生信息
// 关闭事务
}
/**
* 查询学生信息
*/
@Test
public void testQuery(){
DaoTransaction daoTransaction = new DaoTransaction();
StudentServiceImpl studentService = new StudentServiceImpl();
ProxyStudent proxyStudent = new ProxyStudent(studentService, daoTransaction);
Student student = proxyStudent.query(1L);
System.out.println(student);
// Student(name=张三, age=18)
}
}
- 存在问题:
1.不利于代码的扩展,比如在接口中新添加一个抽箱方法时,所有的实现类都需要重新实现,否则报错。
2.代理对象需要创建很多,这种设计很不方便。
JDK动态代理
- 创建service接口
/**
* @Author sima
* @Date 2023/4/25 18:00
*/
public interface IStudentService {
/**
* 添加学生
*/
void save();
/**
* 查询学生信息
* @param id
* @return
*/
Student query(Long id);
}
- service实现类(需要代理的类)
/**
* @Author sima
* @Date 2023/4/25 18:05
*/
public class StudentServiceImpl implements IStudentService {
@Override
public void save() {
System.out.println("保存学生信息");
}
@Override
public Student query(Long id) {
Student student = new Student();
student.setName("张三");
student.setAge(18);
return student;
}
}
- 实现InvocationHandler接口
InvocationHandler接口,用来做方法拦截
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @Author sima
* @Date 2023/4/25 19:32
*/
public class TranscationHandler implements InvocationHandler {
//增强类对象
private DaoTransaction transaction;
//需要代理的目标对象
private Object obj;
public TranscationHandler(DaoTransaction transaction,Object obj){
this.transaction = transaction;
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object ret = null;
//判断当前方法是否是save,是才做事务拦截
if ("save".equals(method.getName())) {
transaction.before();
ret = method.invoke(obj,args);
transaction.after();
}else{
ret = method.invoke(obj,args);
}
return ret;
}
}
- 测试方法
import org.junit.Test;
import java.lang.reflect.Proxy;
/**
* @Author sima
* @Date 2023/4/25 18:19
*/
public class TestStudent {
/**
* 保存学生信息
*/
@Test
public void testSave(){
//增强类对象
DaoTransaction daoTransaction = new DaoTransaction();
//目标执行类
StudentServiceImpl studentService = new StudentServiceImpl();
//方法拦截处理器
TranscationHandler transcationHandler = new TranscationHandler(daoTransaction, studentService);
//创建代理实例对象
IStudentService proxyInstance = (IStudentService)Proxy.newProxyInstance(StudentServiceImpl.class.getClassLoader(), StudentServiceImpl.class.getInterfaces(), transcationHandler);
proxyInstance.save();
System.out.println(proxyInstance);
// 开启事务
// 保存学生信息
// 关闭事务
}
}
InvocationHandler invoke里面的参数
proxy:代理实例,可以通过newProxyInstance创建代理实例
Methed:执行目标对象的,invoke方法执行
args:参数数组
Proxy.newProxyInstance 里面的参数
ClassLoader:类加载器
Class<?>[]:目标类实现的所有接口
InvocationHandler:方法拦截处理器,在里面实现方法的加强
源码分析
ublic static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
//检查InvocationHandler是否为空,为空抛出空指针异常
Objects.requireNonNull(h);
//克隆拿到接口
final Class<?>[] intfs = interfaces.clone();
//进行安全校验
final SecurityManager sm = System.getSecurityManager();
//检查是否能被代理
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
/*
* Look up or generate the designated proxy class.
* 查找或生成指定的代理类(这一步生成代理对象的class)
* 这行代码最重要,它可以得到一个代理对象
*/
Class<?> cl = getProxyClass0(loader, intfs);
/*
* Invoke its constructor with the designated invocation handler.
* 使用指定的调用处理程序调用其构造函数。
* 见下一段代码
*/
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
//通过类对象获取构造器对象
final Constructor<?> cons = cl.getConstructor(constructorParams);
final InvocationHandler ih = h;
if (!Modifier.isPublic(cl.getModifiers())) {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
cons.setAccessible(true);
return null;
}
});
}
//new得到代理对象
//获得的代理对象是存这样一个在有参构造
//将InvocationHandler 通过构造器注入到代理对象中
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}
Class<?> cl = getProxyClass0(loader, intfs);
/**
* Generate a proxy class. Must call the checkProxyAccess method
* to perform permission checks before calling this.
* 生成代理类。必须调用checkProxyAccess方法以在调用此之前执行权限检查。
*
*/
private static Class<?> getProxyClass0(ClassLoader loader,
Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// If the proxy class defined by the given loader implementing 如果由实现的给定加载程序定义的代理类
// the given interfaces exists, this will simply return the cached copy;如果给定的接口存在,这将简单地返回缓存的副本;
// otherwise, it will create the proxy class via the ProxyClassFactory否则,它将通过ProxyClassFactory创建代理类
return proxyClassCache.get(loader, interfaces);
}
proxyClassCache.get(loader,interfaces)
public V get(K key, P parameter) {
Objects.requireNonNull(parameter);
expungeStaleEntries();
//从缓存中取出代理类的key(classLoader),因为代理类的生成需要耗时间和性能,所有缓存起来方便下次直接使用,
Object cacheKey = CacheKey.valueOf(key, refQueue);
// lazily install the 2nd level valuesMap for the particular cacheKey 延迟安装特定cacheKey的第二级值映射
ConcurrentMap<Object, Supplier<V>> valuesMap = map.get(cacheKey);
if (valuesMap == null) {
ConcurrentMap<Object, Supplier<V>> oldValuesMap
= map.putIfAbsent(cacheKey,
valuesMap = new ConcurrentHashMap<>());
if (oldValuesMap != null) {
valuesMap = oldValuesMap;
}
}
// create subKey and retrieve the possible Supplier<V> stored by that
// subKey from valuesMap
Object subKey = Objects.requireNonNull(subKeyFactory.apply(key, parameter));
Supplier<V> supplier = valuesMap.get(subKey);
Factory factory = null;
while (true) {
if (supplier != null) {
// supplier might be a Factory or a CacheValue<V> instance 供应商可能是工厂或CacheValue<V>实例
V value = supplier.get();
if (value != null) {
//返回代理类
return value;
}
}
// else no supplier in cache 缓存中没有
// or a supplier that returned null (could be a cleared CacheValue 或返回null的供应商(可能是已清除的CacheValue
// or a Factory that wasn't successful in installing the CacheValue) 或未成功安装CacheValue的工厂)
// lazily construct a Factory
if (factory == null) {
通过classLoader 和 接口信息 创建一个工厂
factory = new Factory(key, parameter, subKey, valuesMap);
}
if (supplier == null) {
supplier = valuesMap.putIfAbsent(subKey, factory);
if (supplier == null) {
// successfully installed Factory 已成功安装工厂
//将工厂赋值给supplier
//下一次循环调用supplier的git方法 也就是工厂对象的git方法
supplier = factory;
}
// else retry with winning supplier
} else {
if (valuesMap.replace(subKey, supplier, factory)) {
// successfully replaced
// cleared CacheEntry / unsuccessful Factory
// with our Factory
//将工厂赋值给supplier
supplier = factory;
} else {
// retry with current supplier
supplier = valuesMap.get(subKey);
}
}
}
}
supplier.get():WeakCache.Factory#get()
@Override
public synchronized V get() { // serialize access
// re-check
Supplier<V> supplier = valuesMap.get(subKey);
if (supplier != this) {
// something changed while we were waiting:
// might be that we were replaced by a CacheValue
// or were removed because of failure ->
// return null to signal WeakCache.get() to retry
// the loop
return null;
}
// else still us (supplier == this)
// create new value
V value = null;
try {
//key是调构造器传入的new ProxyClassFactory()
//执行ProxyClassFactory的apply方法
value = Objects.requireNonNull(valueFactory.apply(key, parameter));
} finally {
if (value == null) { // remove us on failure
valuesMap.remove(subKey, this);
}
}
// the only path to reach here is with non-null value
assert value != null;
// wrap value with CacheValue (WeakReference)
CacheValue<V> cacheValue = new CacheValue<>(value);
// put into reverseMap
reverseMap.put(cacheValue, Boolean.TRUE);
// try replacing us with CacheValue (this should always succeed)
if (!valuesMap.replace(subKey, this, cacheValue)) {
throw new AssertionError("Should not reach here");
}
// successfully replaced us with new CacheValue -> return the value
// wrapped by it
return value;
}
}
Proxy.ProxyClassFactory#apply()
@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
//获取到所有实现接口
Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
/*
* Verify that the class loader resolves the name of this
* interface to the same Class object.
*/
Class<?> interfaceClass = null;
try {
//对接口再次装载,相当classLoader.loadClass
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* Verify that the Class object actually represents an
* interface.
* 判断两个接口是不是同一个接口(同一个类加载器加载的):判断对象是否是同一个
*/
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* Verify that this interface is not a duplicate.
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
//代理对象的包名
String proxyPkg = null; // package to define proxy class in
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;
/*
* Record the package of a non-public proxy interface so that the
* proxy class will be defined in the same package. Verify that
* all non-public proxy interfaces are in the same package.
*/
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
//判断接口的类型是否是public,如果不是public,将代理类放到目标对象同一目录下
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));
if (proxyPkg == null) {
proxyPkg = pkg;
} else if (!pkg.equals(proxyPkg)) {
throw new IllegalArgumentException(
"non-public interfaces from different packages");
}
}
}
if (proxyPkg == null) {
// if no non-public proxy interfaces, use com.sun.proxy package (默认定义包名)如果没有非公共代理接口,请使用com.sun.proxy包
proxyPkg = ReflectUtil.PROXY_PACKAGE + ".";
}
/*
* Choose a name for the proxy class to generate.
*/
long num = nextUniqueNumber.getAndIncrement();
//标识:private static final String proxyClassNamePrefix = "$Proxy";
//随机数(防止多线程测试相同的类名):long num = nextUniqueNumber.getAndIncrement();
//代理类的名字:代理包名+ 标识+ 随机数
String proxyName = proxyPkg + proxyClassNamePrefix + num;
/*
* Generate the specified proxy class.
* 生成指定的代理类 生成class 的 byte[]
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
try {
//产生代理类,返回一个class:将byte字节码转换成class
//defineClass0是一个native方法,由JVM实现的:private static native Class<?> defineClass0();
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
} catch (ClassFormatError e) {
/*
* A ClassFormatError here means that (barring bugs in the
* proxy class generation code) there was some other
* invalid aspect of the arguments supplied to the proxy
* class creation (such as virtual machine limitations
* exceeded).
*/
throw new IllegalArgumentException(e.toString());
}
}
}
代理对象的字节码文件
/**
* @Author sima
* @Date 2023/4/25 18:19
*/
public class TestStudent {
/**
* 保存学生信息
*/
@Test
public void testSave() throws IOException {
//增强类对象
DaoTransaction daoTransaction = new DaoTransaction();
//目标执行类
StudentServiceImpl studentService = new StudentServiceImpl();
//方法拦截处理器
TranscationHandler transcationHandler = new TranscationHandler(daoTransaction, studentService);
//创建代理实例对象
IStudentService proxyInstance = (IStudentService)Proxy.newProxyInstance(StudentServiceImpl.class.getClassLoader(),
StudentServiceImpl.class.getInterfaces(), transcationHandler);
proxyInstance.save();
// 开启事务
// 保存学生信息
// 关闭事务
saveProxyClass();
}
/**
* 使用来生成字节码学习使用
*/
public void saveProxyClass() throws IOException {
byte[] bytes = ProxyGenerator.generateProxyClass("$proxy1", StudentServiceImpl.class.getInterfaces());
FileOutputStream fileOutputStream = new FileOutputStream(new File("E:\\$proxy1.class"));
fileOutputStream.write(bytes);
}
}
反编译后
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
import com.adc.da.JdkProxy.IStudentService;
import com.adc.da.JdkProxy.Student;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
/**
* 通过接口创建的代理类 继承Proxy 实现IStudentService
*/
public final class $proxy1 extends Proxy implements IStudentService {
// 静态代码块中通过反射得到目标的Method
private static Method m1;
private static Method m4;
private static Method m3;
private static Method m2;
private static Method m0;
//构造方法 在Proxy.newProxyInstance调用该方法实例化,注入自定义的InvocationHandler
public $proxy1(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 Student query(Long var1) throws {
try {
return (Student)super.h.invoke(this, m4, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void save() throws {
try {
// super.h在构造方法中已赋值,h.invoke真实执行重写的transcationHandler.invoke
// invoke 中分别调了增强方法、通过反射调用目标方法。
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
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"));
m4 = Class.forName("com.adc.da.JdkProxy.IStudentService").getMethod("query", Class.forName("java.lang.Long"));
m3 = Class.forName("com.adc.da.JdkProxy.IStudentService").getMethod("save");
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 动态代理
- 实现方法拦截MethodInterceprot
/**
* @Author sima
* @Date 2023/4/26 8:00
*/
public class CglibInterceptor implements MethodInterceptor {
DaoTransaction transaction;
public CglibInterceptor(DaoTransaction transaction){
this.transaction = transaction;
}
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
// 事务增强
transaction.before();
// 目标方法
methodProxy.invokeSuper(o,objects);
transaction.after();
return null;
}
}
- 测试代码
/**
* @Author sima
* @Date 2023/4/25 18:19
*/
public class TestStudent {
/**
* 保存学生信息
*/
@Test
public void testSave() throws IOException {
//生成目标代理类
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"E:\\");
//得到方法拦截器
CglibInterceptor cglibInterceptor = new CglibInterceptor(new DaoTransaction());
//使用CGLIB框架生成目标类的字类(代理类)
Enhancer enhancer = new Enhancer();
//设置父类字节码
enhancer.setSuperclass(StudentServiceImpl.class);
//设置拦截处理器
enhancer.setCallback(cglibInterceptor);
IStudentService studentService = (IStudentService)enhancer.create();
studentService.save();
// 开启事务
// 保存学生信息
// 关闭事务
}
}
- 代理类反编译
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 StudentServiceImpl$$EnhancerByCGLIB$$f83062aa extends StudentServiceImpl 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$save$0$Method;
private static final MethodProxy CGLIB$save$0$Proxy;
private static final Object[] CGLIB$emptyArgs;
private static final Method CGLIB$query$1$Method;
private static final MethodProxy CGLIB$query$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 var0 = Class.forName("com.adc.da.cglib.StudentServiceImpl$$EnhancerByCGLIB$$f83062aa");
Class var1;
Method[] var10000 = ReflectUtils.findMethods(new String[]{"save", "()V", "query", "(Ljava/lang/Long;)Lcom/adc/da/cglib/Student;"}, (var1 = Class.forName("com.adc.da.cglib.StudentServiceImpl")).getDeclaredMethods());
CGLIB$save$0$Method = var10000[0];
CGLIB$save$0$Proxy = MethodProxy.create(var1, var0, "()V", "save", "CGLIB$save$0");
CGLIB$query$1$Method = var10000[1];
CGLIB$query$1$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Long;)Lcom/adc/da/cglib/Student;", "query", "CGLIB$query$1");
var10000 = ReflectUtils.findMethods(new String[]{"equals", "(Ljava/lang/Object;)Z", "toString", "()Ljava/lang/String;", "hashCode", "()I", "clone", "()Ljava/lang/Object;"}, (var1 = Class.forName("java.lang.Object")).getDeclaredMethods());
CGLIB$equals$2$Method = var10000[0];
CGLIB$equals$2$Proxy = MethodProxy.create(var1, var0, "(Ljava/lang/Object;)Z", "equals", "CGLIB$equals$2");
CGLIB$toString$3$Method = var10000[1];
CGLIB$toString$3$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/String;", "toString", "CGLIB$toString$3");
CGLIB$hashCode$4$Method = var10000[2];
CGLIB$hashCode$4$Proxy = MethodProxy.create(var1, var0, "()I", "hashCode", "CGLIB$hashCode$4");
CGLIB$clone$5$Method = var10000[3];
CGLIB$clone$5$Proxy = MethodProxy.create(var1, var0, "()Ljava/lang/Object;", "clone", "CGLIB$clone$5");
}
final void CGLIB$save$0() {
super.save();
}
public final void save() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
// 执行MehodIntercept的方法
var10000.intercept(this, CGLIB$save$0$Method, CGLIB$emptyArgs, CGLIB$save$0$Proxy);
} else {
super.save();
}
}
final Student CGLIB$query$1(Long var1) {
return super.query(var1);
}
public final Student query(Long var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return var10000 != null ? (Student)var10000.intercept(this, CGLIB$query$1$Method, new Object[]{var1}, CGLIB$query$1$Proxy) : super.query(var1);
}
final boolean CGLIB$equals$2(Object var1) {
return super.equals(var1);
}
public final boolean equals(Object var1) {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
Object var2 = var10000.intercept(this, CGLIB$equals$2$Method, new Object[]{var1}, CGLIB$equals$2$Proxy);
return var2 == null ? false : (Boolean)var2;
} else {
return super.equals(var1);
}
}
final String CGLIB$toString$3() {
return super.toString();
}
public final String toString() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return var10000 != null ? (String)var10000.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() {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
if (var10000 != null) {
Object var1 = var10000.intercept(this, CGLIB$hashCode$4$Method, CGLIB$emptyArgs, CGLIB$hashCode$4$Proxy);
return var1 == null ? 0 : ((Number)var1).intValue();
} else {
return super.hashCode();
}
}
final Object CGLIB$clone$5() throws CloneNotSupportedException {
return super.clone();
}
protected final Object clone() throws CloneNotSupportedException {
MethodInterceptor var10000 = this.CGLIB$CALLBACK_0;
if (var10000 == null) {
CGLIB$BIND_CALLBACKS(this);
var10000 = this.CGLIB$CALLBACK_0;
}
return var10000 != null ? var10000.intercept(this, CGLIB$clone$5$Method, CGLIB$emptyArgs, CGLIB$clone$5$Proxy) : super.clone();
}
public static MethodProxy CGLIB$findMethodProxy(Signature var0) {
String var10000 = var0.toString();
switch(var10000.hashCode()) {
case -508378822:
if (var10000.equals("clone()Ljava/lang/Object;")) {
return CGLIB$clone$5$Proxy;
}
break;
case -34064223:
if (var10000.equals("query(Ljava/lang/Long;)Lcom/adc/da/cglib/Student;")) {
return CGLIB$query$1$Proxy;
}
break;
case 1826985398:
if (var10000.equals("equals(Ljava/lang/Object;)Z")) {
return CGLIB$equals$2$Proxy;
}
break;
case 1872760024:
if (var10000.equals("save()V")) {
return CGLIB$save$0$Proxy;
}
break;
case 1913648695:
if (var10000.equals("toString()Ljava/lang/String;")) {
return CGLIB$toString$3$Proxy;
}
break;
case 1984935277:
if (var10000.equals("hashCode()I")) {
return CGLIB$hashCode$4$Proxy;
}
}
return null;
}
public StudentServiceImpl$$EnhancerByCGLIB$$f83062aa() {
CGLIB$BIND_CALLBACKS(this);
}
public static void CGLIB$SET_THREAD_CALLBACKS(Callback[] var0) {
CGLIB$THREAD_CALLBACKS.set(var0);
}
public static void CGLIB$SET_STATIC_CALLBACKS(Callback[] var0) {
CGLIB$STATIC_CALLBACKS = var0;
}
private static final void CGLIB$BIND_CALLBACKS(Object var0) {
StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var1 = (StudentServiceImpl$$EnhancerByCGLIB$$f83062aa)var0;
if (!var1.CGLIB$BOUND) {
var1.CGLIB$BOUND = true;
Object var10000 = CGLIB$THREAD_CALLBACKS.get();
if (var10000 == null) {
var10000 = CGLIB$STATIC_CALLBACKS;
if (var10000 == null) {
return;
}
}
var1.CGLIB$CALLBACK_0 = (MethodInterceptor)((Callback[])var10000)[0];
}
}
public Object newInstance(Callback[] var1) {
CGLIB$SET_THREAD_CALLBACKS(var1);
StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var10000 = new StudentServiceImpl$$EnhancerByCGLIB$$f83062aa();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Callback var1) {
CGLIB$SET_THREAD_CALLBACKS(new Callback[]{var1});
StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var10000 = new StudentServiceImpl$$EnhancerByCGLIB$$f83062aa();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
}
public Object newInstance(Class[] var1, Object[] var2, Callback[] var3) {
CGLIB$SET_THREAD_CALLBACKS(var3);
StudentServiceImpl$$EnhancerByCGLIB$$f83062aa var10000 = new StudentServiceImpl$$EnhancerByCGLIB$$f83062aa;
switch(var1.length) {
case 0:
var10000.<init>();
CGLIB$SET_THREAD_CALLBACKS((Callback[])null);
return var10000;
default:
throw new IllegalArgumentException("Constructor not found");
}
}
public Callback getCallback(int var1) {
CGLIB$BIND_CALLBACKS(this);
MethodInterceptor var10000;
switch(var1) {
case 0:
var10000 = this.CGLIB$CALLBACK_0;
break;
default:
var10000 = null;
}
return var10000;
}
public void setCallback(int var1, Callback var2) {
switch(var1) {
case 0:
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var2;
default:
}
}
public Callback[] getCallbacks() {
CGLIB$BIND_CALLBACKS(this);
return new Callback[]{this.CGLIB$CALLBACK_0};
}
public void setCallbacks(Callback[] var1) {
this.CGLIB$CALLBACK_0 = (MethodInterceptor)var1[0];
}
static {
CGLIB$STATICHOOK1();
}
}
总结
- JDK动态代理有一个前提,需要代理的类必须实现接口,如果没有实现接口,只能通过CGLIB来实现,其实就是对JDK动态代理的一个补充。
- 使用CGLIB 代理,类不能被final 修饰,方法不能被final 修饰,因为不能继承,重写。
代理类型 | 实现机制 | 回调方式 | 使用场景 |
---|---|---|---|
JDK动态代理 | 通过实现接口,通过反射机制获取到接口里面的方法,并且自定义InvocationHandler接口,实现方法拦截 | 调用invoke方法实现增强 | 目标类有接口 |
CGLIB动态代理 | 继承机制,通过继承重写目标方法,使用MethodInterceptor 调用父类的目标方法从而实现代理 | 调用MethodInterceptor中 interceptor方法 | 不用final修饰的类和方法 |