动态代理学习笔记

来源:互联网 发布:绿色自行车是什么软件 编辑:程序博客网 时间:2024/05/17 23:12

1、有一个接口,


/**
 * 移动接口
 * @author Administrator
 *
 */
public interface Moveable {
    void move();   
}

有一个实现类--》坦克类

/**
 * 模拟坦克
 * 实现移动接口
 * @author Administrator
 *
 */
public class Tank implements Moveable {

    @Override
    public void move() {
        System.out.println("Tank moving...");  
    }
}

2、当需要对move方法做日志处理,但是不能改动源码,怎么办?

这里引入静态代理,静态代理类需要是接口的实现类,还需要包含该接口的成员变量

/**
 * 计算未知源码方法的另一种方式
 * 聚合,代理,更好
 * 使用代理,可以加判断,检测是否有调用方法的权限
 * 可以记录调用方法的相关日志
 * @author Administrator
 *
 */
public class TankLogProxy implements Moveable {
    Moveable m;

    public TankLogProxy(Moveable m){
        super();
        this.m = m;
    }
    @Override
    public void move() {
        System.out.println("Tank is start...");
        m.move();
        System.out.println("Tank is end...");    
    }
}

3、但是,我们不仅需要对该方法做日志处理,还需要做异常处理、事务控制、权限认证,

这个时候,需要引入动态代理,这样我们就可以只处理业务逻辑就可以

查看Java API,它有相应的接口,我们可以直接实现,然后动态生成我们需要的代理类,

/**
 * 动态代理
 * 生成各种代理对象的工厂
 * @author Administrator
 *
 */
public class ProxyFactory implements InvocationHandler {
    private Object target;
    public ProxyFactory(Object target){
        this.target = target;
    }
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
    
    public Object productProxyObject(){
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(), this);
    }
    
    /**
     * Object proxy代理类
     * Method method代理类的方法
     * Object[] args方法的参数
     * 被代理的方法调用处
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("方法执行之前");
        Object result = method.invoke(target, args);
        System.out.println("方法执行之后");
        return result;
    }
}

4、查看API,

Proxy 提供用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类。

有个静态方法newProxyInstance,返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序

public static Object newProxyInstance(ClassLoader loader,                                      Class<?>[] interfaces,                                      InvocationHandler h)                               throws IllegalArgumentException
参数:
loader - 定义代理类的类加载器
interfaces - 代理类要实现的接口列表
h - 指派方法调用的调用处理程序
5、

InvocationHandler 是代理实例的调用处理程序 实现的接口。

只有一个方法Objectinvoke(Object proxy,Method method, Object[] args) throws Throwable

参数:
proxy - 在其上调用方法的代理实例
method - 对应于在代理实例上调用的接口方法的 Method 实例。Method 对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口。
args - 包含传入代理实例上方法调用的参数值的对象数组,如果接口方法不使用参数,则为 null。基本类型的参数被包装在适当基本包装器类(如java.lang.Integerjava.lang.Boolean)的实例中。
6、自己找的一些资料,整理下,可能不是很清楚,但现在是能够知道些,怕忘了。

有空研究下。

0 0
原创粉丝点击