Java web个人学习Java学习笔记系列

代理简记

2020-05-06  本文已影响0人  SonyaBaby
代理.png

Java静态代理 委托类和代理类,实现共同接口

共同接口:

public interface HelloService {
    void sayHello();
}

委托类:

public class Hello implements HelloService{

    @Override
    public void sayHello() {
        System.out.println("hi, this is Hello-Original.");
    }
}

代理类:

public class HelloProxy implements HelloService {

    private Hello source = new Hello();

    @Override
    public void sayHello() {
        before();
        source.sayHello();
        after();
    }

    private void before(){
        System.out.println("Before hello, I need prepare something...");
    }

    private void after(){
        System.out.println("After hello, I need conclude something...");
    }
}

测试结果:

public static void main(String[] args) {
        HelloProxy helloProxy = new HelloProxy();
        helloProxy.sayHello();
    }

Before hello, I need prepare something...
hi, this is Hello-Original.
After hello, I need conclude something...

Java动态代理 通过反射生成代理类
实现 InvocationHandler 通过 Proxy.newProxyInstance 构建

public class JavaProxyInvocationHandler implements InvocationHandler {

    private Object obj;

    public JavaProxyInvocationHandler(Object obj){
        this.obj = obj;
    }

    public Object newProxyInstance(){
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }

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

测试结果:

public static void main(String[] args) {
        JavaProxyInvocationHandler proxyHandler = new JavaProxyInvocationHandler(new Hello());
        HelloService helloService = (HelloService) proxyHandler.newProxyInstance();
        helloService.sayHello();
    }

obj invoked before...
hi, this is Hello-Original.
obj invoked after...

CGLib 动态代理 底层将方法全部存入一个数组中,通过数组索引直接进行方法调用
方法调用:通过字节码文件生成委托类的子类,对非 final 委托方法生成两个方法:委托方法签名相同的方法,它在方法中会通过super调用委托方法;代理类独有的方法,它会判断是否存在实现了MethodInterceptor接口的对象,若存在则将调用intercept方法对委托方法进行代理。

public class HelloMethodInterceptor implements MethodInterceptor {
    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("HelloMethodInterceptor: before...");
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("HelloMethodInterceptor: after...");
        return object;
    }
}

测试结果:

public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Hello.class);
        enhancer.setCallback(new HelloMethodInterceptor());
        Hello hello = (Hello) enhancer.create();
        hello.sayHello();
    }

HelloMethodInterceptor: before...
hi, this is Hello-Original.
HelloMethodInterceptor: after...

CGLib 细节可以参考 深入理解CGLIB动态代理机制0 写的挺不错的

上一篇 下一篇

猜你喜欢

热点阅读