woieha320r的博客

代理

· 作为中介在方法前后执行其他操作,需要对外透明——同类型同方法签名,外界不直接调用被代理类,调用代理,被代理类由代理负责调用。所以在被代理类内部调用
自己的方法是和代理无关的,代理行为不会生效。
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;

import java.lang.reflect.Proxy;

interface BeProxy {
    void hello(String msg);
}

class BeProxyImpl implements BeProxy {
    @Override
    public void hello(String msg) {
        System.out.println("Hello " + msg + " !");
    }

    public static void main(String[] args) {
        //非代理
        System.out.println("非代理");
        BeProxy beProxy = new BeProxyImpl();
        beProxy.hello("World");

        //jdk动态代理,通过生成实现了被代理类相同接口的实现类作为代理来实现对外透明,那么被代理方法必须声明在接口中
        System.out.println("\njdk动态代理");
        ((BeProxy) Proxy.newProxyInstance(BeProxy.class.getClassLoader(), BeProxyImpl.class.getInterfaces(), ((proxy, method, arguments) -> {
            System.out.println("before");
            Object returnVal = method.invoke(beProxy, arguments);
            System.out.println("after");
            return returnVal;
        }))).hello("World");

        //cglib动态代理,通过生成继承自被代理类的子类作为代理来实现对外透明,那么被代理方法必须是可被继承的:非final、static...
        //避免直接访问字段,访问的会是子类(代理)的字段,但cglib生成的子类不负责初始化字段
        System.out.println("\ncglib动态代理");
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(BeProxyImpl.class);
        enhancer.setCallback((MethodInterceptor) (obj, method, arguments, methodProxy) -> {
            System.out.println("before");
            Object returnVal = methodProxy.invokeSuper(obj, arguments);
            System.out.println("after");
            return returnVal;
        });
        ((BeProxyImpl) enhancer.create()).hello("World");
    }
}