常用设计模式--代理模式

代理模式是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。

代理又分为静态代理和动态代理,我们一般指的都是动态代理。

在 Java 中,动态代理有两种:JDK 动态代理cglib 动态代理

JDK代理

接口

public interface HelloWorld {
    void sayHelloWorld();
}

实现类

public class HelloWorldImpl implements HelloWorld{
    @Override
    public void sayHelloWorld() {
        System.out.println("Hello world");
    }
}

代理类

public class JdkProxyExample implements InvocationHandler {

    /*
        这个就是我们要代理的真实对象
     */
    private Object target = null;

    //返回代理类的一个实例,返回后的代理类可以当作被代理类使用
    /*
    static Object newProxyInstance(ClassLoaderloader, Class[] interfaces, InvocationHandler h)
    第一参数:类加载器
    第二参数:创建袋里实例需要的一组接口
    第三参数:整合了业务逻辑和横切逻辑的编织器对象
     */
    public Object bind(Object target){
        this.target = target;
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),this);
    }


    /*
        第一个参数proxy一般是指代理类,
        method是被代理的方法,如上例中的request(),
        args为该方法的参数数组。
        这个抽象方法在代理类中动态实现。
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("进入代理逻辑方法");
        System.out.println("在调度真实对象之前的服务");
        Object obj = method.invoke(target, args);
        System.out.println("在调度真实对象之后的服务");
        return obj;
    }
}

测试类

public class TestMain {
    public static void main(String[] args) {
        JdkProxyExample jdk = new JdkProxyExample();
        //将代理的实例传入,返回真实的代理对象
        HelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());
        //真实代理对象调用方法
        proxy.sayHelloWorld();
    }
}

结果

可以看出,jdk 代理的重点在于 Proxy.newProxyInstance() 方法和 invoke() 方法。

代理类继承了Proxy类并且实现了要代理的接口,由于java不支持多继承,所以JDK动态代理不能代理类,只能代理接口。


cglib代理

使用 cglib 代理需要单独导入相应的 jar包

被代理类

public class SayHello {
    public void sey(String name){
        System.out.println("Hello "+ name);
    }
}

代理类

public class CglbProxyExample implements MethodInterceptor {

    public Object getProxy(Class cls){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(cls);
        enhancer.setCallback(this);
        return enhancer.create();
    }

    @Override
    public Object intercept(Object obj, Method method,
                            Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("调用真实对象前");
        Object result = methodProxy.invokeSuper(obj, objects);
        System.out.println("调用真实对后");
        return result;
    }
}

测试类

public class TestCglibMain {
    public static void main(String[] args) {
        CglbProxyExample cglib = new CglbProxyExample();
        SayHello proxy = (SayHello) cglib.getProxy(SayHello.class);
        proxy.sey("张三");
    }
}
posted @ 2020-11-17 16:28  乐子不痞  阅读(41)  评论(0编辑  收藏  举报
回到顶部