最终是学习AOP(面向切面编程),它与装饰者模式有点相似,它比装饰者模式还要灵活!
目标对象:被增强的对象
代理对象:需要目标对象,然后在目标对象上添加了增强后的对象!
目标方法:增强的内容
代理对象 = 目标对象 + 增强
public interface MyInterface {
void fun1();
void fun2();
}
public class MyInterfaceImpl implements MyInterface {
public void fun1() {
System.out.println("fun1()");
}
public void fun2() {
System.out.println("fun2()");
}
}
上面的代码对我们来说没有什么新鲜感,我们要说的是动态代理技术可以通过一个方法调用就可以生成一个对指定接口的实现类对象。
Class[] cs = {MyInterface.class}; MyInterface mi = (MyInterface)Proxy.newProxyInstance(loader, cs, h);
这个对象实现了cs数组中指定的接口。没错,返回值mi是MyInterface接口的实现类。你不要问这个类是哪个类,你只需要知道mi是MyInterface接口的实现类就可以了。你现在也不用去管loader和h这两个参数是什么东东,你只需要知道,Proxy类的静态方法newProxyInstance()方法返回的方法是实现了指定接口的实现类对象,甚至你都没有看见实现类的代码。
动态代理就是在运行时生成一个类,这个类会实现你指定的一组接口,而这个类没有.java文件,是在运行时生成的,你也不用去关心它是什么类型的,你只需要知道它实现了哪些接口即可。
newProxyInstance()方法的参数
Proxy类的newInstance()方法有三个参数:
ClassLoader loader:它是类加载器类型,你不用去理睬它,你只需要知道怎么可以获得它就可以了:MyInterface.class.getClassLoader()就可以获取到ClassLoader对象,没错,只要你有一个Class对象就可以获取到ClassLoader对象;
Class[] interfaces:指定newProxyInstance()方法返回的对象要实现哪些接口,没错,可以指定多个接口,例如上面例子只我们只指定了一个接口:Class[] cs = {MyInterface.class};
InvocationHandler h:它是最重要的一个参数!它是一个接口!它的名字叫调用处理器!你想一想,上面例子中mi对象是MyInterface接口的实现类对象,那么它一定是可以调用fun1()和fun2()方法了,难道你不想调用一下fun1()和fun2()方法么,它会执行些什么东东呢?其实无论你调用代理对象的什么方法,它都是在调用InvocationHandler的invoke()方法!