动态代理
与静态代理区别
1.代理类在程序运行时根据我们在java代码中的“指示”创建代理的方式被称为动态代理。而静态代理在程序编译的时候就已经将接口,被代理类,代理类确定下来了。
2.相比与静态代理,动态代理的优势在于可以很方便的对代理类的函数进行统一的处理,而不用说修改每个代理类中的方法。
比如说:在静态代理中,班长帮学生交学费,静态代理中有giveMoney()方法,里面调用的是stu.giveMoney(),我们可以在交学费之前做一些处理,比如打印该学生所需交的费用,如果这时又有另外一个交伙食费的方法,我们同样需要在交伙食费之前打印费用信息,这时,需要再次在stu.giveFoodMoney()方法之前添加打印方法,这样一来,打印费用方法就要写很多次,而动态代理,只需写一次即可。
动态代理实现原理
jdk的动态代理主要是通过Proxy类和InvocationHandler接口生成JDK动态代理类和动态代理对象。
其中:InvocationHandler用于表示在执行某个方法之前,之后你想加入什么(监控)代码。Proxy用于自动生成代理类,InvocationHandler将会作为Proxy的一个参数来生成代理类。
两者通过Proxy.newInstance()方法进行关联,invocationHandler会作为参数传入Proxy, 由Proxy在编译的时候加工自动生成代理类,这个生成的代理类里就会有invocationHandler里指定的要执行的代码。
下面贴上两个主要的代码段:实现的主函数及InvocationHandler
//实现的主函数
public class ProxyTest {
public static void main(String[] args) {
//创建一个实例对象,这个对象是被代理的对象
Person zhangsan = new Student("张三");
//创建一个与代理对象相关联的InvocationHandler
//创建一个代理对象stuProxy来代理zhangsan,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, new StuInvocationHandler<Person>(zhangsan));
//代理执行上交班费的方法
stuProxy.giveMoney();
}
}
//InvocationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class StuInvocationHandler<T> implements InvocationHandler {
T target;
public StuInvocationHandler(T target){
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行"+method.getName()+"方法");
MonitorUtil.start(); //这是一个本地静态工具类,用于记下方法开始时间
Object result = method.invoke(target, args);
MonitorUtil.finish(method.getName());//这是一个本地静态工具类,用于记下方法执行完成的时间
return result;
}
}