学习设计模式-代理模式

174 阅读4分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

源码在分支master

代理模式:

image.png

静态代理

image.png

优缺点

image.png

代码结构

image.png

Code实现

/*******************************************************************************
 * Package: com.example.demo.design.proxy.staticproxy
 * Type:    ILog
 * Date:    2022-04-10 13:40
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.staticproxy;

/**
 * 功能描述: 日志接口
 * 静态代理:
 * 优点:对目标方法 功能增强
 * 缺点:不易于维护
 * @author Songxianyang
 * @date 2022-04-10 13:40
 */
public interface ILog {
    /**
     * 打印日志
     */
    void pint();
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.staticproxy
 * Type:    ILogImpl
 * Date:    2022-04-10 13:40
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.staticproxy;

/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-10 13:40
 */
public class LogImpl implements ILog {
    @Override
    public void pint() {
        System.out.println("打印日志");
    }
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.staticproxy
 * Type:    LogProxy
 * Date:    2022-04-10 13:42
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.staticproxy;

/**
 * 功能描述:
 * 实现对方法的增强
 * @author Songxianyang
 * @date 2022-04-10 13:42
 */
public class LogProxy implements ILog {
    private ILog iLog;
    
    public LogProxy(ILog iLog) {
        this.iLog = iLog;
    }
    
    @Override
    public void pint() {
        //这边写的可以是业务方法:比喻:事务的开启
        System.out.println("开启事务-----");
        //执行目标方法:可以做判断 是否有异常  有  回滚 无  提交
        iLog.pint();
        //假设 无
        System.out.println("提交事务-----");
    }
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.staticproxy
 * Type:    Test
 * Date:    2022-04-10 13:47
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.staticproxy;

/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-10 13:47
 */
public class Test {
    public static void main(String[] args) {
        // 目标类
        ILog log = new LogImpl();
        // 代理类
        LogProxy proxy = new LogProxy(log);
        
        // 调用代理中的方法
        proxy.pint();
    }
}

运行截图

image.png

动态代理

image.png

image.png

结构

image.png

/*******************************************************************************
 * Package: com.example.demo.design.proxy.staticproxy
 * Type:    ILog
 * Date:    2022-04-10 13:40
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.dynamic;

/**
 * 功能描述: 日志接口
 * 动态代理:jdk 代理   接口代理
 * 优点:对目标方法 功能增强
 * 缺点:易于维护
 * @author Songxianyang
 * @date 2022-04-10 13:40
 */
public interface ILog {
    /**
     * 打印日志
     */
    void pint();
    
    /**
     * 打印一个数
     */
    void num( int i);
    
    int count(int j);
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.staticproxy
 * Type:    ILogImpl
 * Date:    2022-04-10 13:40
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.dynamic;


/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-10 13:40
 */
public class LogImpl implements ILog {
    @Override
    public void pint() {
        System.out.println("打印日志");
    }
    
    @Override
    public void num(int i) {
        System.out.println(i);
    }
    
    @Override
    public int count(int j) {
        return j;
    }
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.dynamic
 * Type:    LogProxyFactory
 * Date:    2022-04-10 14:13
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.dynamic;

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

/**
 * 功能描述:
 * 代理工厂
 * @author Songxianyang
 * @date 2022-04-10 14:13
 */
public class LogProxyFactory {
    /**
     * 目标对象
     */
    private Object target;
    
    public LogProxyFactory(Object target) {
        this.target = target;
    }
    
    /**
     * 获取目标对象实例
     * @return
     */
    public Object getTargetExample() {
      return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("jdk 代理开始");
                        // 两个参数进行说明 1、目标类 2、参数数组
                        Object invoke = method.invoke(target, args);
                        System.out.println("jdk 代理结束");
                        return invoke;
                    }
                });
        
    }
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.dynamic
 * Type:    Test
 * Date:    2022-04-10 14:21
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.dynamic;

/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-10 14:21
 */
public class Test {
    public static void main(String[] args) {
        ILog log = new LogImpl();
        LogProxyFactory factory = new LogProxyFactory(log);
        // 强制类型转换 要转成 接口的类型  特别奇怪
        ILog logn = (ILog) factory.getTargetExample();
        //logn.pint();
        //logn.num(99);
        System.out.println(logn.count(9));
    }
}

运行测试

image.png

cglib 动态代理

image.png

结构

image.png

/*******************************************************************************
 * Package: com.example.demo.design.proxy.cjlib
 * Type:    Log
 * Date:    2022-04-10 16:56
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.cjlib;

/**
 * 功能描述:cglib 代理
 * 对象代理  并不需要来代理接口
 *
 *
 * @author Songxianyang
 * @date 2022-04-10 16:56
 */
public class Log {
    public void pint() {
        System.out.println("SteveCode 在学习 cglib 动态代理 哈哈");
    }
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.cjlib
 * Type:    ProxyFactory
 * Date:    2022-04-10 16:57
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.cjlib;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-10 16:57
 */
public class ProxyFactory implements MethodInterceptor {
    /**
     * 目标对象
     */
    private Object target;
    
    public ProxyFactory(Object target) {
        this.target = target;
    }
    
    /**
     * 获取代理对象 比较重要
     */
    public Object getTargetExample() {
        // 创建工具类
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(target.getClass());
        // 设置回调函数
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    }
    
    /**
     * 方法增强
     * @param o
     * @param method 代理对象中的执行方法
     * @param args 参数
     * @param methodProxy 代理的方法
     * @return
     * @throws Throwable
     */
    @Override
    public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        System.out.println("cglib 代理方法的增强~~~~");
        Object invoke = method.invoke(target, args);
        System.out.println("cglib 代理方法的提交~~~~");
        return invoke;
    }
}
/*******************************************************************************
 * Package: com.example.demo.design.proxy.cjlib
 * Type:    Test
 * Date:    2022-04-10 17:10
 *
 * Copyright (c) 2022 HUANENG GUICHENG TRUST CORP.,LTD All Rights Reserved.
 *
 * You may not use this file except in compliance with the License.
 *******************************************************************************/
package com.example.demo.design.proxy.cjlib;

/**
 * 功能描述:
 *
 * @author Songxianyang
 * @date 2022-04-10 17:10
 */
public class Test {
    public static void main(String[] args) {
        // 目标对象
        Log log = new Log();
        //获取代理工厂
        ProxyFactory factory = new ProxyFactory(log);
        // 或缺代理对象
        Log log2 = (Log) factory.getTargetExample();
        // 执行被代理的方法
        log2.pint();
        
    }
}

运行结果

image.png