代理模式与动态代理深入理解

一,代理模式的简单认识

1.参与者: 代理对象,被代理对象

代理对象相当于现实生活中的房产中介被代理对象
相当于 房东

2.目的:保护被代理对象

避免外界直接修改被代理对象,破坏掉被代理对象原本的功能。
将对被代理对象功能的增强放在代理对象中,
代理对象中存在一个对被代理对象的引用,在使用被代理对象之前或者之后,代理对象可以做一些额外的添油加醋方法。
(这符合开闭原则: 对修改关闭,对拓展开放
代理模式与动态代理深入理解_第1张图片

被代理对象 ProxyObjected.java

package src.com.liu.proxy;
//被代理对象(房东)
public class ProxyObjected {
    public void process(){
        System.out.println("我是被代理对象的方法 process");
    }
}

代理对象 ProxyObject.java

package src.com.liu.proxy;
//代理对象(中介)
public class ProxyObject {
    private ProxyObjected obj;
    ProxyObject(ProxyObjected obj){
        this.obj = obj;
    }
    public void process(){
        ProxyObjected obj = this.obj;

        System.out.println("====被代理对象的方法执行之前,执行添油加醋的动作");
        //执行被代理对象
        obj.process();
        System.out.println("====被代理对象的方法执行之后,执行一些添油加醋的动作");
    }
}

测试代码

package src.com.liu.proxy;

public class Test {
    public static void main(String[] args) {
            //创建被代理对象
            ProxyObjected obj = new ProxyObjected();
            //创建代理对象(把被代理对象当作参数传入)
            ProxyObject proxyObject = new ProxyObject(obj);
            //执行代理对象的方法(先执行添油加醋,再执行被代理对象的process,再执行添油加醋)
            proxyObject.process();
    }

}

代理模式与动态代理深入理解_第2张图片

二,动态代理

动态代理的意思是我们不直接生成我们的proxyObject,
而是提供 1.被代理对象和 2.增强方法(那些添油加醋方法)3.以及各自调用时机,然后在代码运行时自动帮我们生成一个proxyObject。
好处: 将代理对象方法和增强方法(添油加醋方法)解耦分离,使代码更具拓展型和可维护性。

这里只讲jdk动态代理

2.1 被代理对象 TestDao.java

package src.com.liu.proxy.dynamic.jdk;

public interface TestDao {
    public void save();
    public void modify();
    public void delete();
}

2.2 被代理对象实现类 TestDaoImpl.java

package src.com.liu.proxy.dynamic.jdk;

public class TestDaoImpl implements TestDao{
    @Override
    public void save() {
        System.out.println("保存");
    }

    @Override
    public void modify() {
        System.out.println("修改");
    }

    @Override
    public void delete() {
        System.out.println("删除");
    }
}

2.3 代理对象的增强方法 类 Enhancement.java

package src.com.liu.proxy.dynamic.jdk;
//代理对象的增强方法 类
public class Enhancement {
    public void check(){
        System.out.println("模拟权限控制");
    }
    public void except(){
        System.out.println("模拟异常处理");
    }
    public void log(){
        System.out.println("模拟日志记录");
    }
    public  void monitor(){
        System.out.println("性能监测");
    }
}

2.4 代理对象类 JDKDynamicProxy.java

package src.com.liu.proxy.dynamic.jdk;

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

//代理对象类
public class JDKDynamicProxy implements InvocationHandler
{
    private TestDao testDao;//被代理对象
    JDKDynamicProxy(TestDao dao){
        this.testDao= dao;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Enhancement enhancement = new Enhancement();
        enhancement.check();
        enhancement.except();

        //调用被代理对象方法
        Object obj = method.invoke(testDao,args);

        enhancement.log();
        enhancement.monitor();
        return  obj;
    }
}

2.5 JDKDynamicTest.java

package src.com.liu.proxy.dynamic.jdk;

import java.lang.reflect.Proxy;

public class JDKDynamicTest {
    public static void main(String[] args) {
        //创建被代理对象
        TestDao testDao = new TestDaoImpl();
        //创建代理对象,并将被代理对象注入到代理对象中
        JDKDynamicProxy jdkDynamicProxy = new JDKDynamicProxy(testDao);


        //得到一个类加载器
        ClassLoader classLoader = JDKDynamicProxy.class.getClassLoader();
        //得到被代理对象的所有接口
        Class[] clazz = testDao.getClass().getInterfaces();
        //生成代理对象
        TestDao testDaoAdvice = (TestDao) Proxy.newProxyInstance(classLoader,clazz,jdkDynamicProxy);

        //执行方法
        testDaoAdvice.save();
        System.out.println("====================");
        testDaoAdvice.modify();
        System.out.println("====================");
        testDaoAdvice.delete();
    }
}

2.6效果:
代理模式与动态代理深入理解_第3张图片

2.7 改变 Enhancement.java类中增强方法里的内容时,不改变现有代码运行
代理模式与动态代理深入理解_第4张图片
运行结果:
代理模式与动态代理深入理解_第5张图片
这实现了 代理对象里那些添油加醋增强方法 的结偶,
当这些增强方法需要修改时,不用动代理对象类里的代码

你可能感兴趣的:(java,代理模式,java,开发语言)