代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。通俗的来讲代理模式就是我们生活中常见的中介。
静态代理其实就是指设计模式中的代理模式。代理模式为其他对象提供一种代理以控制对这个对象的访问。
静态代理是在程序运行之前,代理类.class文件就已经被创建。 缺点,接口改变代理类也需要改变。
动态代理,在程序运行是通过反射机制来动态创建。
使用代理的好处:就是生活中的中介。不用关心代理的工作流程。
1、动态代理是什么?
动态代理是反射的一个非常重要的应用场景。动态代理常常被用于一些java框架中。例如Spring AOP等
2、两种--JDK动态代理和CGLIB动态代理
JDK动态代理: 利用反射机制生成一个实现代理接口的匿名类。在调用具体的方法之前调用InvokeHandler来处理。
CGLIB动态代理:利用asm开源包,对代理对象class文件加载进来,通过修改其字节码生成子类来处理。
JDK动态代理
动态不需要手动常见代理类。编写一个动态处理器就可以了。
image.png image.png image.png
newProxyInstance方法的参数:ClassLoader ,Class<?>[] interfaces,InvocationHandler
1.指定当前目标对象使用的类加载器,获取加载器的方法是固定的。
2.指定目标对象实现的接口的类型,使用泛型方式确认类型。
3.指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法。
优点: 减少了开发任务。减少了对接口的依赖。缺点:并没有摆脱interface。
CGLIB代理:
JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要CGLib了。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。但因为采用的是继承,所以不能对final修饰的类进行代理。JDK动态代理与CGLib动态代理均是实现Spring AOP的基础。
第一步---是经过一系列操作实例化出了Enhance对象,并设置了所需要的参数然后enhancer.create()成功创建出来了代理对象。
第二步----调用代理对象的eat()方法,会进入到方法拦截器的intercept()方法,在这个方法中会调用proxy.invokeSuper(obj, args);
第三步-----invokeSuper中,通过FastClass机制调用目标类的方法
当我们去调用方法一的时候,在代理类中会先判断是否实现了方法拦截的接口,没实现的话直接调用目标类的方法一;如果实现了那就会被方法拦截器拦截,在方法拦截器中会对目标类中所有的方法建立索引,其实大概就是将每个方法的引用保存在数组中,我们就可以根据数组的下标直接调用方法,而不是用反射;索引建立完成之后,方法拦截器内部就会调用invoke方法(这个方法在生成的FastClass中实现),在invoke方法内就是调用CGLIB这种方法,也就是调用对应的目标类的方法一;
网友评论