SpringAOP 动态代理
1.实现方式:JDK动态代理和CGLIB动态代理
2.动态代理特点
1.目标对象不固定
2.在应用程序执行时动态创建目标对象
3.代理对象会增强目标对象的行为
3.JDK动态代理
package com.xxx.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK动态代理类
*/
public class JDKHandler implements InvocationHandler {
//目标对象 类型不固定 创建时动态生产
private Object target;
//通过带参构造传递目标对象
public JDKHandler(Object target) {
this.target = target;
}
/**
* 1.调用目标对象方法(返回object)
* 2.增强目标对象行为
* @param proxy 调用方法代理实例
* @param method 目标对象方法
* @param args 目标对象方法需要的参数
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//增强行为
System.out.println("before");
Object object=method.invoke(target,args);
return object;
}
public Object getProxy(){
/**
* 三个参数:Classloader loader,Class[] interface, InvocationHandler h
* loader:类加载器
* interface:接口数组
* h:接口的实现类
*/
Object object= Proxy.newProxyInstance(this.getClass().getClassLoader(),
target.getClass().getInterfaces(),this);
return object;
}
}
实现方法
public static void main(String[] args) {
Man man=new Man();
JDKHandler jdkHandler=new JDKHandler(man);
//得到代理对象
Marry marry=(Marry) jdkHandler.getProxy();
//执行invoke()
marry.toMarry();
}
4.CGLIB动态代理
区别
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能使用JDK的动态代理
cglib是针对类来实现代理的,它的原理是对指定的目标类生成一个子类, 并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
JDK动态代理实现接口,Cglib动态代理继承思想
JDK动态代理(目标对象存在接口时)执行效率高于Ciglib
如果目标对象有接口实现,选择JDK代理,如果没有接口实现选择Cglib代理
public class cglibInterceptor implements MethodInterceptor {
//目标对象
private Object target;
//通过构造器传入目标对象
public cglibInterceptor(Object target) {
this.target = target;
}
//获取代理对象
public Object getProxy(){
//通过Enhancer对象中的create()方法生成一个类,用来代理对象
Enhancer enhancer =new Enhancer();
//设置父类 将目标类作为代理类的父类
enhancer.setSuperclass(target.getClass());
// 设置拦截器 回调对象为本身对象
enhancer.setCallback(this);
// 生成代理对象并返回
return enhancer.create();
}
/**
* 拦截器
* 1.目标对象的方法调用
* 2.行为增强
* @param o cgilb动态生产的代理类实例
* @param method 实体类所调用的都被代理的方法的引用
* @param objects 参数列表
* @param methodProxy 生产的代理类对方法的代理引用
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
//调用目标类中的方法
Object object=methodProxy.invoke(target,objects);
//增强行为
return null;
}
}
实现
public static void main(String[] args) {
//得到目标对象
Dog d=new Dog();
//得到拦截器
CglibInterceptor cglibInterceptor=new CglibInterceptor(d);
//得到代理对象
Aninmal aninmal=(Aninmal) cglibInterceptor.getProxy();
//通过代理对象调用目标对象的方法
aninmal.fun();
//没有接口实现的类 JDK代理不可以实现
User user=new User();
CglibInterceptor cglibInterceptor1=new CglibInterceptor(user);
User u=(User) cglibInterceptor1.getProxy();
u.test();
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix