动态代理


因为动态代码会使得代码会翻倍。要使用动态代理。

动态代理代理的是抽象对象也就是接口!!!

反射机制

 动态代理和静态代理的角色分析都是一致的

    抽象角色,真实角色,代理角色(这里动态生成) 客户端

  动态代理的代理类是动态生成的,不像静态代理模式那样我们直接写死的!

    动态代理是真正使用的时候才去建立代理关系!

  动态代理分为两大类:基于接口实现;基于类实现 

  接口:InvocationHandler(java.lang.reflect包下)     会用调用这个接口的类,生成动态代理类

    他是调用处理程序实现的接口

  类:Proxy(代理)类

    Proxy提供了创建动态代理类和实例的静态方法

  实现动态代理的步骤:

    抽象角色(接口)

public interface UserInterface {
    public void add();
    public void delete();
    public void update();
    public void select();
}

    真实角色

package com.chen.dao;

public class UserImpl implements UserInterface{

    public void add() {
        System.out.println("增加了一个用户");
    }

    public void delete() {
        System.out.println("删除了一个用户");
    }

    public void update() {
        System.out.println("更新了一个用户");
    }

    public void select() {
        System.out.println("查找了一个用户");
    }

}

    抽象角色生成

package com.chen.dao;

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

public class InvocationHandlerImpl  implements InvocationHandler {
    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //自己写一个方法生成代理类 【死代码】                   反射里面 newInstance()就能获得对象了
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }


    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //动态代理的本质,就是反射
        //动态代理专属的方法,在这里写
        getMessage(method.getName());
        //这里是动态代理对象调用真实对象方法
        Object result = method.invoke(target, args);//需要传递对象和参数 意思是:哪个对象(target)调用method方法,传递的参数是args
        getMessage(method.getName());
        return result;
    }

    public void getMessage(String msg){
        System.out.println("调用了"+msg+"方法");
    }

}

    客户端去使用抽象角色调用方法

package com.chen.dao;

public class Client {
    public static void main(String[] args) {
        //真实角色
        UserImpl user = new UserImpl();
        //生成动态代理角色
        InvocationHandlerImpl invocationHandler = new InvocationHandlerImpl();
        //处理我们的接口对象
        invocationHandler.setTarget(user);
        //生成代理对象
        UserInterface proxy = (UserInterface)invocationHandler.getProxy();
        //代理对象去调用方法
        proxy.add();


    }
}