设计模式 - 动态代理

需要了解"静态代理", 请查看上一篇文章设计模式-静态代理
解决的问题: 静态代理中的代理类, 每一个代理都要创建一个代理类, 会造成类数量膨胀.

动态代理: 动态返回一个代理对象

动态代理的实现方式

方式1: jdk动态代理(必须有接口)

方式2: cglib动态代理(可以没有接口)

import org.junit.Test;

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

/**
 * 功能说明:动态代理
 * 静态代理: 针对每一个委托类都创建一个代理类
 * 静态代理解决的问题: 增强委托类的功能
 * 动态代理: 对所有的委托类, 使用动态代理, 需要的时候动态生成代理类
 * 动态代理解决的问题: 1, 增强委托类的功能; 2, 解决静态代理类数量膨胀的问题(动态产生代理类, 而无需手动创建每一个代理类代码)
 * 开发人员:@author MaLi
 */
public class T05_DynamicProxy {
    
    

    @Test
    public void MT() {
    
    
        IAction action = new ActionImpl();
        InvocationHandler handler = new ActionHandler(action);
        //创建代理类: 关键语法
        //参数1: 类加载器
        //参数2: 接口数组(委托类的接口"们")
        //参数3: 代理类的动作(代表要对委托类进行的增强)
        IAction proxyAction = (IAction) Proxy.newProxyInstance(T05_DynamicProxy.class.getClassLoader(), action.getClass().getInterfaces(), handler);
        //执行增强之后的动作
        proxyAction.doAction();
    }


    /**
     * 条件1: 具备接口
     */
    static interface IAction {
    
    
        void doAction();
    }

    /**
     * 条件2: 委托类(被代理的类, 也就是要增强的那个类)
     */
    static class ActionImpl implements IAction {
    
    
        @Override
        public void doAction() {
    
    
            System.out.println("委托类中的doAction方法");
        }
    }

    //条件3: InvocationHandler实现, 代理类的动作(代理类由JDK动态产生, 需要告诉JDK代理类的具体增强方法)
    static class ActionHandler implements InvocationHandler {
    
    
        private IAction actionInstance;

        public ActionHandler(IAction actionInstance) {
    
    
            this.actionInstance = actionInstance;
        }

        // 代理类的动作
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    
    
            //代理处理动作...
            System.out.println("代理类中: 委托类中的doAction方法之前");
            //委托类的方法执行
            method.invoke(actionInstance);
            //代理处理动作...
            System.out.println("代理类中: 委托类中的doAction方法之后");
            return null;//根据逻辑是否要传回值
        }
    }
}

猜你喜欢

转载自blog.csdn.net/malipku/article/details/120778020