动态代理jdk的Proxy与spring的CGlib(jdk代理和动态代理的区别)

  本篇文章为你整理了动态代理jdk的Proxy与spring的CGlib(jdk代理和动态代理的区别)的详细内容,包含有动态代理 jdk jdk代理和动态代理的区别 jdk的动态代理原理和cglib的动态代理 jdkcglib动态代理区别 动态代理jdk的Proxy与spring的CGlib,希望能帮助你了解 动态代理jdk的Proxy与spring的CGlib。

  1. 为什么要使用动态代理?

  动态代理:在不改变原有代码的情况下上进行对象功能增强 使用代理对象代替原来的对象完成功能 进而达到拓展功能的目的

  2.JDK Proxy 动态代理面向接口的动态代理

  特点:

  一定要有接口和实现类的存在 代理对象增强的是实现类 在实现接口的方法重写的方法

  生成的代理对象只能转换成 接口的不能转换成 被代理类

  代理对象只能增强接口中定义的方法 实现类中其他和接口无关的方法是无法增强的

  代理对象只能读取到接口中方法上的注解 不能读取到实现类方法上的注解
 

  使用方法:

  

public class Test1 {

 

   public static void main(String[] args) {

   Dinner dinner=new Person("张三");

   // 通过Porxy动态代理获得一个代理对象,在代理对象中,对某个方法进行增强

  // ClassLoader loader,被代理的对象的类加载器

   ClassLoader classLoader = dinner.getClass().getClassLoader();

  // Class ? [] interfaces,被代理对象所实现的所有接口

   Class[] interaces= dinner.getClass().getInterfaces();

  // InvocationHandler h,执行处理器对象,专门用于定义增强的规则

   InvocationHandler handler = new InvocationHandler(){

   // invoke 当我们让代理对象调用任何方法时,都会触发invoke方法的执行

   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

  // Object proxy, 代理对象

  // Method method,被代理的方法

  // Object[] args,被代理方法运行时的实参

   Object res=null;

   if(method.getName().equals("eat")){

   System.out.println("饭前洗手");

   // 让原有的eat的方法去运行

   res =method.invoke(dinner, args);

   System.out.println("饭后刷碗");

   }else{

   // 如果是其他方法,那么正常执行就可以了

   res =method.invoke(dinner, args);

   return res;

   Dinner dinnerProxy =(Dinner) Proxy.newProxyInstance(classLoader,interaces,handler);

   //dinnerProxy.eat("包子");

   dinnerProxy.drink();

  interface Dinner{

   void eat(String foodName);

   void drink();

  class Person implements Dinner{

   private String name;

   public Person(String name) {

   this.name = name;

   @Override

   public void eat(String foodName) {

   System.out.println(name+"正在吃"+foodName);

   @Override

   public void drink( ) {

   System.out.println(name+"正在喝茶");

  class Student implements Dinner{

   private String name;

   public Student(String name) {

   this.name = name;

   @Override

   public void eat(String foodName) {

   System.out.println(name+"正在食堂吃"+foodName);

   @Override

   public void drink( ) {

   System.out.println(name+"正在喝可乐");

  

 

  3.CGlib动态代理

  cglib动态代理模式是面向父类

  特点:

  
面向父类的和接口没有直接关系
 

  2.不仅可以增强接口中定义的方法还可以增强其他方法
 

  3.可以读取父类中方法上的所有注解

  
enhancer.setSuperclass(person.getClass());

   // 3 获取MethodIntercepter对象 用于定义增强规则

   MethodInterceptor methodInterceptor=new MethodInterceptor() {

   @Override

   public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

   /*Object o, 生成之后的代理对象 personProxy

   Method method, 父类中原本要执行的方法 Person eat()

   Object[] objects, 方法在调用时传入的实参数组

   MethodProxy methodProxy 子类中重写父类的方法 personProxy eat()

   Object res =null;

   if(method.getName().equals("eat")){

   // 如果是eat方法 则增强并运行

   System.out.println("饭前洗手");

   res=methodProxy.invokeSuper(o,objects);

   System.out.println("饭后刷碗");

   }else{

   // 如果是其他方法 不增强运行

   res=methodProxy.invokeSuper(o,objects); // 子类对象方法在执行,默认会调用父类对应被重写的方法

   return res;

   // 4 设置methodInterceptor

   enhancer.setCallback(methodInterceptor);

   // 5 获得代理对象

   Person personProxy = (Person)enhancer.create();

   // 6 使用代理对象完成功能

   personProxy.eat("包子");

  class Person {

   public Person( ) {

   public void eat(String foodName) {

   System.out.println("张三正在吃"+foodName);

  

 

 

  两个动态代理的区别

  JDK动态代理是面向接口的,只能增强实现类中接口中存在的方法。CGlib是面向父类的,可以增强父类的所有方法

  JDK得到的对象是JDK代理对象实例,而CGlib得到的对象是被代理对象的子类

  以上就是动态代理jdk的Proxy与spring的CGlib(jdk代理和动态代理的区别)的详细内容,想要了解更多 动态代理jdk的Proxy与spring的CGlib的内容,请持续关注盛行IT软件开发工作室。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: