代理顾名思义就是代理别人完成某件任务,比如张三代理李四去交物业费。张三就是代理人,李四就是被代理人。
Java代理实现,有静态代理和动态代理,静态代理就是代码在编译成class文件后,就已经有代理类的class文件了,但是动态代理需要在运行时动态生成一个代理类的class,比如:
Class<?> stuProxyClass = Proxy.getProxyClass(Person.class.getClassLoader(), new Class<?>[] {Person.class});
运行时动态生成一个学生的代理类。
代理主要用来做代码功能的增强,比如spring里面的aop(比如面向切面做一个controller日志增强,就不用每个controller里面写日志),事务都是通过动态代理来实现的,jdk适用于被代理对象需要实现接口,而cglib无需被代理对象实现了接口。有时候,比如我们使用了第三方的jar里面的某个类,我们想对他做功能增强,但是又不能改代码?咋办?动态代理就可以帮助我们实现了,我们为这个需要增强的类做一个代理。在代理里面拦截方法,继而做功能增强。本文写的两个demo,一个模拟订单服务,一个模拟用户服务。在新增订单时,通过代理类打印订单数据的日志。新增用户时,打印用户信息。
动态代理有两种实现方式:
方式一:通过JDK自带的反射实现
java.lang.reflect.InvocationHandler和java.lang.reflect.Proxy;
jdk实现的需要有一个接口
OrderService.java接口:
package com.figo.study2022.service;
import java.util.Map;
/**
 * @ClassName:OrderService
 * @PackageName:com.figo.study2022.service.impl
 * @Description:类描述
 * @Date:2022/9/19 20:24
 * @Author:figo
 */
public interface OrderService {
    public void addOrder(Map<String,Object> params);
}
OrderServiceImpl.java实现类
package com.figo.study2022.service.impl;
import com.figo.study2022.service.OrderService;
import java.util.Map;
/**
 * @ClassName:OrderServiceImpl
 * @PackageName:com.figo.study2022.service.impl
 * @Description:类描述
 * @Date:2022/9/19 20:26
 * @Author:figo
 */
public class OrderServiceImpl implements OrderService {
    @Override
    public void addOrder(Map<String, Object> params) {
        System.out.println("add Order 成功!");
    }
}
OrderServiceProxy.java增强处理类
package com.figo.study2022.service.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
 * @ClassName:OrderServiceProxy
 * @PackageName:com.figo.study2022.service.proxy
 * @Description:类描述
 * @Date:2022/9/19 21:11
 * @Author:figo
 */
public class OrderServiceProxy implements InvocationHandler {
    private Object realObj;
    public Object getRealObj() {
        return realObj;
    }
    public void setRealObj(Object realObj) {
        this.realObj = realObj;
    }
    public OrderServiceProxy(Object realObj) {
        super();
        this.realObj = realObj;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if(args!=null&&args.length>0) {
            int size=args.length;
            StringBuffer buffer=new StringBuffer();
            for(int a=0;a<size;a++)
            {
                buffer.append(args[a]);
                buffer.append(",");
            }
            System.out.println("代理OrderService对象做日志增强,获取到的参数为=" + buffer.toString());
        }
        Object ret = method.invoke(realObj,args);
        return ret;
    }
}
Test.java测试类
package com.figo.study2022;
import com.figo.study2022.service.OrderService;
import com.figo.study2022.service.impl.OrderServiceImpl;
import com.figo.study2022.service.impl.UserServiceImpl;
import com.figo.study2022.service.proxy.OrderServiceProxy;
import com.figo.study2022.service.proxy.UserServiceProxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName:Test
 * @PackageName:com.figo.study2022
 * @Description:类描述
 * @Date:2022/9/19 20:29
 * @Author:figo
 */
public class Test {
    public static void main(String[] args) {
        OrderService orderService = new OrderServiceImpl();
        Map<String,Object> params=new HashMap<String,Object>();
        params.put("orderId","20220919204100001");
        params.put("orderTime","20220919204100");
        params.put("orderAmt",100);
        /**
         * 1.通过jdk反射来实现动态代理
         * java.lang.reflect.InvocationHandler
         */
        //写法一:通过匿名对象来代理,这样写免去写代理类
        OrderService proxyOrderService =  (OrderService) Proxy.newProxyInstance(orderService.getClass().getClassLoader(), orderService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //args表示有几个参数,这里只有一个参数
                System.out.println("代理OrderService做日志增强,收到的请求参数是:"+args[0].toString());
                //这里调用真实对象的方法
                return method.invoke(orderService, args);
            }
        });
        proxyOrderService.addOrder(params);
         //写法二:写个jdk动态代理类来实现
        OrderServiceProxy osp = new OrderServiceProxy(orderService);
        OrderService proxy = (OrderService) Proxy.newProxyInstance(orderService.getClass().getClassLoader(),orderService.getClass().getInterfaces(),osp);
        proxy.addOrder(params);
        
    }
}
方式二:通过第三方CGLIB来实现
UserServiceImpl.java实现类,无需继承接口
package com.figo.study2022.service.impl;
/**
 * @ClassName:UserServiceImpl
 * @PackageName:com.figo.study2022.service.impl
 * @Description:使用cgilib实现动态代理,被代理类无需实现接口
 * @Date:2022/9/20 9:34
 * @Author:figo
 */
public class UserServiceImpl {
    public void addUser(String name,int age,String sex)
    {
        System.out.println("添加用户成功!");
    }
}
UserServiceProxy.java方法拦截类
package com.figo.study2022.service.proxy;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
 * @ClassName:UserServiceProxy
 * @PackageName:com.figo.study2022.service.proxy
 * @Description:类描述
 * @Date:2022/9/20 9:35
 * @Author:figo
 */
public class UserServiceProxy implements MethodInterceptor {
    private Object realObj;
    public Object getRealObj() {
        return realObj;
    }
    public void setRealObj(Object realObj) {
        this.realObj = realObj;
    }
    public UserServiceProxy(Object realObj) {
        super();
        this.realObj = realObj;
    }
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        //参数检查
        if(objects!=null&&objects.length>0) {
            int size=objects.length;
            StringBuffer buffer=new StringBuffer();
            for(int a=0;a<size;a++)
            {
                buffer.append(objects[a]);
                buffer.append(",");
            }
            System.out.println("代理UserService对象做日志增强,获取到的参数为=" + buffer.toString());
        }
        //调用真实对象的方法
        Object ret =method.invoke(realObj,objects);
        return ret;
    }
}
Test.java测试类
package com.figo.study2022;
import com.figo.study2022.service.OrderService;
import com.figo.study2022.service.impl.OrderServiceImpl;
import com.figo.study2022.service.impl.UserServiceImpl;
import com.figo.study2022.service.proxy.OrderServiceProxy;
import com.figo.study2022.service.proxy.UserServiceProxy;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
/**
 * @ClassName:Test
 * @PackageName:com.figo.study2022
 * @Description:类描述
 * @Date:2022/9/19 20:29
 * @Author:figo
 */
public class Test {
    public static void main(String[] args) {
       
        /**
         * 2.通过cglib实现动态代理
         * 有时候调用第三方jar,不方便改动里面的代码,但是又希望做功能增强
         * 可以采用动态代理来实现
         */
         //方法一:通过匿名对象来实现
        UserServiceImpl userServiceImpl = new UserServiceImpl();
        //创建enhancer对象
        Enhancer enhancer  = new Enhancer();
        //设置代理的父类
        enhancer.setSuperclass(UserServiceImpl.class);
        //对方法做拦截
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //参数检查
                if(args!=null&&args.length>0) {
                    int size=args.length;
                    StringBuffer buffer=new StringBuffer();
                    for(int a=0;a<size;a++)
                    {
                        buffer.append(args[a]);
                        buffer.append(",");
                    }
                    System.out.println("代理UserService对象做日志增强,获取到的参数为=" + buffer.toString());
                }
                //调用真实对象的方法s
                return method.invoke(userServiceImpl, args);
            }
        });
        UserServiceImpl userServiceImplProxy = (UserServiceImpl) enhancer.create();
        userServiceImplProxy.addUser("andy",18,"男");
        //方法二:通过代理类来实现
        Enhancer enhancer1 = new Enhancer();
        enhancer1.setSuperclass(UserServiceImpl.class);
        enhancer1.setCallback(new UserServiceProxy(new UserServiceImpl()));
        UserServiceImpl userServiceImplProxy1 = (UserServiceImpl) enhancer.create();
        userServiceImplProxy1.addUser("jane",16,"女");
    }
}
                 
                       
                             
                         
                             
                             
                           
                           
                             本文深入探讨Java中动态代理的两种实现方式:通过JDK自带的反射机制和第三方CGLIB库。介绍了如何利用这些技术进行代码功能增强,例如在不修改原始代码的情况下添加日志记录功能。
本文深入探讨Java中动态代理的两种实现方式:通过JDK自带的反射机制和第三方CGLIB库。介绍了如何利用这些技术进行代码功能增强,例如在不修改原始代码的情况下添加日志记录功能。
           
                     
       
           
                 
                 
                 
                 
                 
                
               
                 
                 
                 
                 
                
               
                 
                 扫一扫
扫一扫
                     
              
             
                   1159
					1159
					
 被折叠的  条评论
		 为什么被折叠?
被折叠的  条评论
		 为什么被折叠?
		 
		  到【灌水乐园】发言
到【灌水乐园】发言                                
		 
		 
    
   
    
   
             
            


 
            