jdk动态代理和cglib动态代理介绍

jdk动态代理和cglib动态代理介绍

传统的日志记录方式,需要在每个需要做日志记录的方法中,逐一添加记录日志的方法,这种方式过于繁琐。
一个项目中的方法有很多,不适用于批量方法的日志记录操作;

衍生jdk动态代理和cglib动态代理2种方式对日志操作进行统一管理
(1)jdk动态代理方式
①:Proxy类是Jdk中自带的一个工具类(反射包下,属于反射的功能),它可以帮我们创建代理类或实例
②:方法newProxyInstance()—用于创建代理对象实例
③:Proxy.newProxyInstance()方法中参数介绍:
参数一:目标对象的类加载器
参数二:目标对象实现的所有接口
参数三:InvocationHandler接口(重写invoke方法后)的实例
注意:InvocationHandler 接口的实现类中—>对代理的目标对象内的方法进行增强操作给目标对象方法前面,后面、返回处、异常处添加额外的功能代码–增强
invoke()方法内的参数介绍:
Object proxy:代理对象实例
Method method:代理对象调用的方法的反射–Method对象实例
Object[] args:调用代理方法时传递进来的参数

注意:
jdk动态代理技术使用前提条件: 目标对象必须要有接口.
优点:这种方式已经解决我们前面所有日记需要的问题。非常的灵活。而且可以方便的在后期进行维护和升级。
缺点:当然使用jdk动态代理,必需要有接口。如果没有接口,就无法使用jdk动态代理技术。
示例:明星(目标对象),经纪人(代理对象),方法(强化品牌代言功能) ,由明星操作改为经纪人操作

代码演示:

public static Object createproxy(Object target){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                /*System.out.println(method);
                System.out.println(Arrays.asList(args));*/

                Object result = null;
                LogUtils.logBefore(method.getName(),args);
                try{
                    //1、执行代理对象的操作
                    result = method.invoke(target,args);
                    //2、增强操作---就是日志记录操作
                    LogUtils.logAfterReturning(method.getName(),result);
                }catch (Exception e){
                    //3、异常处理操作
                    LogUtils.logAfterThrowing(method.getName(),e);
                }
                return result;
            }
        });
    }

(2)cglib动态代理方式
①:cglib跟jdk动态代理的不同是:如果目标对象没有实现接口,
cglib同样可以对其进行增强操作(增强就是在目标就去的前面,后面,返回处,异常处添加额外的功能操作)。
②:cglib动态代理,它不是jdk中自带的代理技术
③: Cglib动态代理,是根据目标对象的字节码来进行修改,并产生一个子类。从而达到增强的效果。
④:new MethodInterceptor()接口:作用和invocationHandler接口功能一致
⑤:intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)方法
参数一:cglib产生的代理对象实例
参数二:调用的方法的反射对象实例
参数三:调用方法时,传递参数
参数四:调用的方法反射对象实例的代理对象
返回值:返回值就是调用代理方法时的返回值
注意:在该方法中增强部分,有关异常的出路需要throw e,对异常进行处理
⑥:创建Cglib代理对象实例—>enhancer.create();

Cglib动态代理的优点:Cglib动态代理要比Jdk动态代理要强,因为它可以在没有接口的情况下。也可以对对象进行增强操作。
缺点:不管是Jdk动态代理,还是Cglib动态代理。都需要我们自己编码去实现这些增强操作。

代码演示:

public static Object createCglibProxy(Object target) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());

        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                try {
                    //前置通知
                    LogUtils.logBefore(method.getName(), args);
                    Object result = method.invoke(target, args);
                    //返回通知
                    LogUtils.logAfterReturning(method.getName(), result);
                    return result;
                } catch (Exception e) {
                    //异常通知
                    LogUtils.logAfterThrowing(method.getName(), e);
                    throw e;
                }
            }
        });
        return enhancer.create();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值