动态代理模式

动态代理的应用:
1、控制权限,将权限交给代理类去控制,例如:用户名不符的不让你访问某些功能,给你跳转等
2、你要访问的对象跟你不在一个网络,需要一个代理中间人帮你调用
动态代理好处:
在编码时,代理逻辑与业务逻辑互相独立,各不影响,没有侵入,没有耦合。
旨在通过一种无耦合的方式来为程序带来增强。而动态代理,就是AOP实现方式中的一种

动态代理后记:20200113
/**
 * 动态代理的应用场景:需求变化比较频繁,有时候需要给某个类【对象】加验证权限,有时候需要给某个类做增强,
 * 但是很多地方都有调用此类【对象】,直接修改此类或对象对其他应用造成影响,此时想到的应该就是动态代理
 * 动态代理相当于造了一个盒子,将【对象】传给盒子,盒子里面可以帮你实现功能增强、权限验证...
 * 使用的原因:https://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/index.html
 * **/



动态代理类中所有方法都是存在接口之中的,否则无法调用

=============客户端类=================
package com.bitz.coin.benifit.test.module_pro;

public class Client {
    public static void main(String[] args) {
        //new一个代理对象,将被代理的接口传入构造函数,获取代理对象
        Subject subjectA = new JDKDynamicProxy(new SubjectA()).getObject();
        //用代理的对象去调用被代理的对象
        subjectA.doSomething();

        System.out.println("=======================");
        new SubjectA().doSomething();

    }
}

============接口==========

package com.bitz.coin.benifit.test.module_pro;

public interface Subject {
    void doSomething();
}

 

============被代理的主类==========

package com.bitz.coin.benifit.test.module_pro;

public class SubjectA implements Subject {
    @Override
    public void doSomething() {
        System.out.println("实现类A,实现Subject接口");
    }
}

============动态代理类==========

package com.bitz.coin.benifit.test.module_pro;

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

/**
 * 场景:
 * 权限控制:为啥不在类中直接控制权限,因为违反单一原则,类功能尽量单一,代理的话就能解决这个问题。
 * webservice,要调用的类在另外一个网络上,代理模式就能解决
 */
public class JDKDynamicProxy implements InvocationHandler {

    private Object target;

    /**
     * 构造方法传入
     */
    public JDKDynamicProxy(Object target) {
        this.target = target;
    }

    /**
     * 获取被代理接口的实例对象
     */
    public  T getObject() {
        return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }

    /**
     * 代理能做的事情,或者代理扩展的功能
     */
    public void proxyPrint() {
        System.out.println("======下面是代理扩展的功能======");
        System.out.println("我是代理类输出的");
    }

    /**
     * 通过方法映射
     * proxy:  指代我们所代理的那个真实对象
     * method: 指代的是我们所要调用真实对象的某个方法的Method对象
     * args:  指代的是调用真实对象某个方法时接受的参数
     */
    String userNmae = "liming";

    //代理不能做的事情交给真正的类去做
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//        权限控制
        if (userNmae.equals("liming")) {
            //代理类拓展的方法
            proxyPrint();
            //下面是代理调用主类的方法
            return method.invoke(target, args);
        }
        return null;
    }
}

你可能感兴趣的:(设计模式)