代理模式---动态代理--cglib

上次说到,cglib是基于类的动态代理。

因为jdk代理是基于接口,有局限性,如果一个类没有继承接口也想实现动态代理的话,必须就要借助于cglib动态代理了。与JDK代理相比较,cglib的原理是创造一个子类重写父类(要被代理的对象)的方法。

cglib的流程

真实角色:要被代理的对象

代理角色:生成代理类(要继承cglib包里的MethodInterceptor接口) 方法拦截器

public interface MethodInterceptor extends Callback {
    Object intercept(Object var1, Method var2, Object[] var3, MethodProxy var4) throws Throwable;
}

第一个参数是就是被代理的对象的引用,第二个参数是对应的方法的引用,第三个对应的参数,第四个为子类的代理。这个方法是处理实例方法的核心方法,用于实现代理对象增强代码的功能,类比于jdk代理的invoke(),

除此 生成代理对象实例要依靠一个类 Enhancer,他有很多api 最常用的就是下面代码中的

    public Object getTarget() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

set父类,也就是要代理的类,

然后setcallback 里面是这个实现拦截器本身的类

然后return enhancer.create() 就获得了一个对象的实例

client角色:调用代理的角色

下面分别贴出代码

真实角色:

package com.heaboy.proxyExcise.cglibProxy;

/**
 * @Author:XK
 * @Date: Created in 17:34 2022/2/19
 * @Description:
 **/
public class Student {
    public void run(){
        System.out.println("学生会跑");
    }
}

代理角色:

package com.heaboy.proxyExcise.cglibProxy;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.springframework.cglib.core.MethodInfoTransformer;

import java.lang.reflect.Method;

/**
 * @Author:XK
 * @Date: Created in 17:34 2022/2/19
 * @Description:
 **/
public class cglibProxyIm implements MethodInterceptor {
    //要代理的类
    private Object target;

    public cglibProxyIm(Object target){
        this.target=target;
    }

    public Object getTarget() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(target.getClass());
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("增强代码1");
        //方式1
        //Object result =methodProxy.invokeSuper(o,objects);
        //方式2
        Object result = method.invoke(target, objects);
        System.out.println("增加功能2");
        return result;
    }
}

client角色:

package com.heaboy.proxyExcise.cglibProxy;

/**
 * @Author:XK
 * @Date: Created in 17:40 2022/2/19
 * @Description:
 **/
public class client {
    public static void main(String[] args) {
        Student student = new Student();
        cglibProxyIm cglibProxyIm = new cglibProxyIm(student);
        Student target = (Student)cglibProxyIm.getTarget();
        target.run();
    }
}

猜你喜欢

转载自blog.csdn.net/Yoke______/article/details/123021720
今日推荐