初认CGlib代理技术

初识CGlib动态代理技术

之前在JDK代理技术提到代理设计模式的三要素:

  1. 有原始类
  2. 额外的方法
  3. 和原始类实现相同的方法

对于CGlib也是一样的

1.和JDK代理模式对比

JDK代理模式

例如:

image-20210531224944924

他们都实现了相同的接口,看代理类和原始类的区别,区别在被代理的对象的方法中添加了额外功能。

同时从这个图可以看出代理类和原始类是兄弟关系。

JDK代理是基于接口实现的,也就是说实现JDK必须要实现接口

而CGlib是基于继承关系,例如

如果一个类没有实现接口,那么如何实现动态代理呢?

image-20210531225445568

CGlib提供了解决方案

可以看出CGlib是基于父子关系,至此,也就解答了之前为啥要使用接口接受代理对象的原因。

2.CGlib动态代理技术的实现

由于是基于继承关系,所以不用在代理实现中实现接口,只需要实现原始类即可

原始类


public class UserServiceImplNew implements UserService {
    @Override
    public void register(User user) {
        System.out.println("UserServiceImplNew.register");
    }

    @Override
    public void login(String name, String password) {
        System.out.println("UserServiceImplNew.login");
    }
}

1.在代理实现中实现原始类

​ 直接new即可

final UserService userService=new UserServiceImplNew();

2.声明增类,以及对对应的方法设置

Enhancer enhancer=new Enhancer();        
//和JDK一样,依然需要提供类加载器
enhancer.setClassLoader(userService.getClass().getClassLoader());
//指定类为父类
enhancer.setSuperclass(userService.getClass());

3.实现MethodInterceptor接口

基本等效于InvocationHandler

MethodInterceptor interceptor =new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                System.out.println("CGlibModle.intercept");
                Object ret=method.invoke(userService,objects);
                return ret;
            }
        };

其中的intercept函数和JDK所需要内容是高度一致的

  • ​ Object o 返回的对象
  • Method method 传入的方法
  • Object[] objects 参数列表
  • MethodProxy methodProxy 代理的方法

根据代理设计模式的三要素中的和原始类实现相同的方法,使用invoke函数传入实现类和参数列表

注意:有的CGlib版本intercept的第二个参数是args这里是objects,其实都一样

4.把代理类创建出来和使用

enhancer.setCallback(interceptor);
UserService userServiceProxy= (UserService) enhancer.create();
userServiceProxy.register(new User());
userServiceProxy.login("SY","123456");

运行结果:

image-20210531231116000

完整代码:

package org.PoxyModle;


import org.User;
import org.UserService;
import org.UserServiceImplNew;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGlibModle {
    public static void main(final String[] args) {
        final UserService userService=new UserServiceImplNew();

        Enhancer enhancer=new Enhancer();
        enhancer.setClassLoader(userService.getClass().getClassLoader());
        enhancer.setSuperclass(userService.getClass());

        MethodInterceptor interceptor =new MethodInterceptor() {
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

                System.out.println("CGlibModle.intercept");
                Object ret=method.invoke(userService,objects);
                return ret;
            }
        };
        enhancer.setCallback(interceptor);
        UserService userServiceProxy= (UserService) enhancer.create();

        userServiceProxy.register(new User());
        userServiceProxy.login("SY","123456");
    }
}

大概就是这个流程

posted on 2021-05-31 23:14  NathenJames  阅读(103)  评论(0编辑  收藏  举报