代理模式

1. 静态代理:

1-1. interface

public interface Hello {

    public void talk();
}

1-2. some impl class

public class HelloImpl implements Hello {

    @Override
    public void talk() {
        System.out.println("hi, helloImpl.");
    }

}

1-3. some proxy class

public class HelloProxy implements Hello {

    private Hello hello;
    public HelloProxy(){
        hello = new HelloImpl();
    }
    @Override
    public void talk() {
        before();
        hello.talk();
        after();
    }

    private void after() {
        System.out.println("do something after talk...");        
    }
    private void before() {
        System.out.println("do something before talk...");
    }
    public static void main(String[] args) {
        HelloProxy hProxy = new HelloProxy();
        hProxy.talk();
    }

}

2. JDK动态代理

2-1 dynamic proxy class(1.0 version)

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

public class DynamicProxy implements InvocationHandler {

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

}

2-2. 测试

import java.lang.reflect.Proxy;

public class TestProxy {

    public static void main(String[] args) {
        Hello hello = new HelloImpl();
        DynamicProxy dProxy = new DynamicProxy(hello);
        Hello helloProxy = (Hello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),
                              hello.getClass().getInterfaces(), 
                              dProxy);
        helloProxy.talk();
    }
}

2-3. dynamic proxy class(2.0 version)

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

public class DynamicProxy implements InvocationHandler {

    private Object target;
    public DynamicProxy (Object target){
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        before();
        Object result = method.invoke(target, args);
        after();
        return result;
        
    }
    public <T> T getProxy(){
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), 
                this);
    }
    private void after() {
        System.out.println("after ...");
    }
    private void before() {
        System.out.println("before....");
    }

}

2-4 Test

import java.lang.reflect.Proxy;

public class TestProxy {

    public static void main(String[] args) {
        DynamicProxy dProxy = new DynamicProxy(new HelloImpl());
        Hello helloProxy = dProxy.getProxy();
        helloProxy.talk();
    }
}

3 CGLIB动态代理

jdk动态代理是基于接口的, 如果一个类没有实现任何接口,这时就不管用了

3-1. CGLib代理类

cglib 提供的是方法级别的代理,也可以理解为对方法的拦截

import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxy implements MethodInterceptor {

    @SuppressWarnings("unchecked")
    public <T> T getProxy(Class<T> cls){
        return (T) Enhancer.create(cls, this);
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args,
            MethodProxy proxy) throws Throwable {
        before();
        Object result = proxy.invokeSuper(obj, args);
        after();
        return result;
    }

    private void after() {
        // TODO Auto-generated method stub
    }

    private void before() {
        // TODO Auto-generated method stub
    }

}

3-2. Test

这里不需要任何的接口信息

public class TestCLIib {

    public static void main(String[] args) {
        CGLibProxy cgLibProxy = new CGLibProxy();
        HelloImpl helloProxy = cgLibProxy.getProxy(HelloImpl.class);
        helloProxy.talk();
    }
}

需要引入asm的相关jar, 引用asm-5.1.2.jar时报错, 引用com.springsource.org.objectweb.asm-3.2.0.jar可以

原文地址:https://www.cnblogs.com/rocky-fang/p/5454773.html