敷衍搪塞网

java动态代理两种实现方式

java动态代理两种实现方式

代理顾名思义就是动态代理代理别人完成某件任务,比如张三代理李四去交物业费。两种张三就是实现代理人,李四就是动态代理被代理人。

Java代理实现,两种有静态代理和动态代理,实现静态代理就是动态代理代码在编译成class文件后,就已经有代理类的两种class文件了,但是实现动态代理需要在运行时动态生成一个代理类的class,比如:

ClassstuProxyClass = 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(Mapparams);}
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(Mapparams) {         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;apackage 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();        Mapparams=new HashMap();        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;apackage 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

未经允许不得转载:敷衍搪塞网 » java动态代理两种实现方式