当前位置 博文首页 > 外星喵的博客:代理模式的三种实现方式及其源码

    外星喵的博客:代理模式的三种实现方式及其源码

    作者:[db:作者] 时间:2021-07-12 15:41

    代理模式

    什么是代理模式

    代理模式的定义: 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

    在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。

    这种类型的设计模式属于结构型模式。

    优点:

    1. 职责清晰。
    2. 高扩展性。
    3. 智能化。

    缺点:

    1. 由于在客户端和真实主题之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢。
    2. 实现代理模式需要额外的工作,有些代理模式的实现非常复杂。

    组成

    • 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。

    • 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。

    • 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用。

    在这里插入图片描述

    实现

    第一种:静态代理

    步骤1:创建一个接口

    public interface IDemo {
    
        public String print();
    }
    

    步骤2: 创建一个该接口的实现类

    public class Demo implements IDemo {
    
        public Demo(){
    
        }
    
        public  String print(){
            System.out.println("this is a demo.");
            return "end";
        }
    }
    

    步骤3:创建一个该接口的代理类,并在代理类初始化的时候接管被代理对象

    public class StaticProxy implements IDemo {
    
        IDemo target;
    
        public StaticProxy(IDemo target) {
            this.target = target;
        }
    
        @Override
        public String print() {
            System.out.println("before print");
            String result = target.print();
            System.out.println("after print");
    
            return "print " + result;
        }
    }
    

    步骤4:执行程序,输出结果:

        public static void main(String[] args) {
            IDemo demo = new StaticProxy(new Demo());
            System.out.println(demo.print());
        }
    

    在这里插入图片描述

    动态代理

    步骤1、2同静态代理

    步骤3: 创建实现InvocationHandler接口的类

    public class ProxyInvocationHandler implements InvocationHandler {
    
        Object target;
    
        public ProxyInvocationHandler(Object obj) {
            target = obj;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before " + method.getName());
            Object result = method.invoke(target, args);
            System.out.println("after " + method.getName());
            return "invoke " + result;
        }
    }
    

    步骤4:创建代理类用以获取Demo类的对象

    public class DynamicProxy {
    
        public static Object getProxyObject(Class clazz) throws Exception {
            ProxyInvocationHandler handler = new ProxyInvocationHandler(new Demo());
            Class c = Proxy.getProxyClass(clazz.getClassLoader(), clazz);
            Constructor con = c.getConstructor(InvocationHandler.class);
            Object o = con.newInstance(handler);
            return o;
        }
        
    }
    

    步骤5:执行程序,输出结果

        public static void main(String[] args) throws Exception {
            IDemo dem = (IDemo) getProxyObject(IDemo.class);
            System.out.println(dem.print());
        }
    

    在这里插入图片描述

    CGLIB代理

    步骤1:Maven引入CGLIB相关依赖

            <dependency>
                <groupId>cglib</groupId>
                <artifactId>cglib</artifactId>
                <version>2.2.2</version>
            </dependency>
    

    步骤2:创建CglibDemo类

    public class CglibDemo{
    
        public String print() {
            System.out.println("this is a cglib demo.");
            return "end";
        }
    }
    

    步骤3:创建一个类CglibInterceptor并实现MethodInterceptor接口

    public class CglibInterceptor implements MethodInterceptor {
    
        Object target;
    
        public CglibInterceptor(Object target) {
            this.target = target;
        }
    
        public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("before " + method.getName());
            Object result = methodProxy.invoke(target, args);
            System.out.println("after " + method.getName());
            return "intercept " + result;
        }
    }
    

    步骤4:创建CGLIB代理类获取被代理后的对象

    public class CglibProxy {
    
    
        private Object target;
    
        public Object getInstance(final Object target) {
            this.target = target;
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(this.target.getClass());
            enhancer.setCallback(new CglibInterceptor(target));
            return enhancer.create();
        }
    }
    

    步骤5:执行程序,输出结果

        public static void main(String[] args) {
            CglibDemo cglibDemo = (CglibDemo) new CglibProxy().getInstance(new CglibDemo());
            System.out.println(cglibDemo.print());
        }
    

    在这里插入图片描述

    cs