jdk动态代理与cglib

jdk动态代理,代理的target需要实现接口,本质是通过反射实现的,动态生成代理类,继承Proxy,实现target的接口,动态调用的时候通过调用InvocationHandle的invoke方法实现
jdk动态代理之所以只能代理接口是因为代理类本身已经extends了Proxy,而java是不允许多重继承的,但是允许实现多个接口

public final class $Proxy11 extends Proxy implements UserService 

cglib代理,底层采用asm字节码生成框架生成代理类的字节码,,,继承了委托类,,生成的代理类是委托类的子类,且不能处理被final关键字修饰的方法

public class UserService$$EnhancerByCGLIB$$394dddeb extends UserService implements Factory
package gj;

import org.assertj.core.internal.cglib.proxy.Enhancer;
import org.assertj.core.internal.cglib.proxy.MethodInterceptor;
import org.assertj.core.internal.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * Description
 *
 * @author leezhao
 * @time 18/5/21
 */
public class ProxyTest {

    public static void main(String[] args) {
        Subject subject = new SubjectImp();
        ProxyHandleIm invocationHandler = new ProxyHandleIm(subject);
        Subject subject1 = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(),subject.getClass().getInterfaces(),invocationHandler);
        subject1.doSomething();
        System.out.println(subject1.getClass());
        System.out.println(subject1 == invocationHandler.getProxyObject());


        System.out.println("------>>>>>>>>>>>");

        Enhancer enhancer =new Enhancer();
        enhancer.setSuperclass(TargetObject.class);
        enhancer.setCallback(new TargetInterceptor());
        TargetObject targetObject2=(TargetObject)enhancer.create();
        System.out.println(targetObject2);
        System.out.println(targetObject2.method1("mmm1"));
        System.out.println(targetObject2.method2(100));
        System.out.println(targetObject2.method3(200));
    }
}

interface Subject{
    void doSomething();
}

class SubjectImp implements Subject{
    @Override
    public void doSomething() {
        System.out.println("do something");
    }
}

class ProxyHandleIm implements InvocationHandler{
    /**
     * 这个就是我们要代理的真实对象
     */
    private Object subject;

    /**
     * 构造方法,给我们要代理的真实对象赋初值
     *
     * @param subject
     */
    public ProxyHandleIm(Object subject)
    {
        this.subject = subject;
    }

    private Object proxyObject;

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("proxy before");
        Object retVal = method.invoke(subject,args);
        System.out.println("proxy after");
        proxyObject = proxy;
        return retVal;
    }

    public Object getProxyObject() {
        return proxyObject;
    }

    public void setProxyObject(Object proxyObject) {
        this.proxyObject = proxyObject;
    }
}

class TargetObject {
    public String method1(String paramName) {
        return paramName;
    }

    public int method2(int count) {
        return count;
    }

    public int method3(int count) {
        return count;
    }

    @Override
    public String toString() {
        return "TargetObject []"+ getClass();
    }
}

class TargetInterceptor implements MethodInterceptor {
    /**
     * 重写方法拦截在方法前和方法后加入业务
     * Object obj为目标对象
     * Method method为目标方法
     * Object[] params 为参数,
     * MethodProxy proxy CGlib方法代理对象
     */
    @Override
    public Object intercept(Object obj, Method method, Object[] params,
                            MethodProxy proxy) throws Throwable {
        System.out.println("调用前");
        Object result = proxy.invokeSuper(obj, params);
        System.out.println(" 调用后"+result);
        return result;
    }
}

注:参考了之前看到的一篇文章,记不清了,就不注明出处了

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010468602/article/details/80689740
个人分类: java
上一篇Linux 定时任务 crontab
下一篇git 常用操作
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭