Aop面向切面动态代理

1、结构图

2、ISuper.class

/**
 * 超人能力
 * 
 * @author zhou
 * 
 */
public interface ISuper {

    void fly();

    void changeBig();

}

3、Man.class

/**
 * 具体实现类,被代理类
 * 
 * @author zhou
 * 
 */
public class Man implements ISuper {

@Override
public void fly() {
    // TODO Auto-generated method stub
    for (int i = 0; i <3; i++) {
        System.out.println("我是超人,我會飛...");
    }
}

@Override
public void changeBig() {
    // TODO Auto-generated method stub
    System.out.println("我是奥特曼,我會飛,我可以变大...");

}

}

4、MyProxy.class

public class MyProxy {

/**
 * 获取一个代理对象,使用父类、接口接受
 * @param t
 * @return
 */
@SuppressWarnings("unchecked")
public static <T> T getProxy(T t) {
    MyInvocationHandler<T> handler = new MyInvocationHandler<T>();
    handler.setT(t);

    return (T) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), handler);

}

}

/**
 *  代理具体实现方法步骤
 * @author zhou
 *
 * @param <T>
 */

class MyInvocationHandler<T> implements InvocationHandler {

T t;

public void setT(T t) {
    this.t = t;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {

    TimeUtils timeUtils = new TimeUtils();
    timeUtils.startTime();
    @SuppressWarnings("unchecked")
    T result = (T) method.invoke(t, args);
    timeUtils.endTime();

    return result;
}
}

5、计算方法执行时间

public class TimeUtils {

    long tempTemp;

    public void startTime() {
        tempTemp = System.currentTimeMillis();
        System.out.println("开始时间:" + System.currentTimeMillis());
    }

    public void endTime() {

        long end = System.currentTimeMillis();
        System.out.println("结束时间:" + end);
        System.out.println("总共时长:" + (end - tempTemp));
    }
}

6、运行使用

public static void main(String[] args) {
        // TODO Auto-generated method stub
        Man m = new Man();
        m.fly();
        m.changeBig();

        System.out.println("===================================");

        ISuper newMan = MyProxy.getProxy(m);
        newMan.fly();
        newMan.changeBig();

    }

其中 ISuper newMan = MyProxy.getProxy(m); 返回的是接口类,而不是具体子类。不然会发生类转换异常,顾名思义,使用代理改变的是父类方法前后插入实现代码,而不是子类,子类继承父类方法,理应该随着父类变化而变化。

这个代理不仅是对Man一个类代理,而是可以对任何具有父类的类代理有效果,去计算执行一个方法的时间。