------- android培训、java培训、期待与您交流! ----------
AOP(Aspect oriented program) 面向方面的编程AOP的目标就是要使交叉业务模块化,可以采用将切面代码移动到原始方法的周围,这与直接在方法中编程切面代码的运行效果是一样的。
1.proxy类:
构造方法:
protected Proxy(InvocationHandler h)
使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的Proxy实例。
方法:
static Object newProxyInstance(ClassLoaderloader,Class<?>[] interfaces, InvocationHandler h) 返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
static Class<?> getProxyClass(ClassLoaderloader,Class<?>... interfaces) 返回代理类的java.lang.Class对象,并向其提供类加载器和接口数组。
static InvocationHandler getInvocationHandler(Objectproxy)返回指定代理实例的调用处理程序。
static boolean isProxyClass(Class<?> cl) 当且仅当指定的类通过 getProxyClass方法或newProxyInstance方法动态生成为代理类时,返回true。
2.InvocationHandler接口:
Object invoke(Object proxy, Methodmethod,Object[] args) 在代理实例上处理方法调用并返回结果。这个方法的proxy就是InvocationHandler所属于的代理对象,method就是代理对象调用的方法,args就是代理对象调用的方法里面的参数。在invoke内部,menthod会调用invoke方法作用于目标对象身上。目标对象即target。
3.创建动态代理类的方法
以Collection接口的动态代理类为例
1).使用Proxy.getProxyClass(ClassLoaderloader,Class<?>... interfaces)方法来获取动态代理类的class,然后在调用这个class的构造方法Proxy(InvocationHandlerh)创建实例。【期间通过反射获取构造方法。】
Collection proxy=(Collection)Proxy.getProxyClass(Collection.class.getClassLoader,Collection.class).getConstrctor(InvocationHandler.class).newInstance(newInvocationHandler(){public Object invoke(Object target,Methodmethod,ObjectparaListOfMethod[]){}})
2).使用Proxy.newProxyInstance(ClassLoaderloader,Class<?>[] interfaces, InvocationHandler h) 方法来直接创建动态代理类的实例
Collection proxy= (Collection)Proxy.newProxyInstance(Collection.class.getClassLoader,Collection.class,new InvocationHandler(){
public Object invoke(Object target,Methodmethod,ObjectparaListOfMethod[]){}
})
怎样将目标类传入代理的Invoke方法中?
把target和系统代码[即我们要在方法前或后面执行的代码]封装成对象,抽到InvocationHandler外面,之后通过参数的方法传递进去。getProxy(tarket,advice)
InvocationHandler类里面只复写了Object里面的equals,toString,hashCode方法。没有复写getClass方法,所以想要获取代理类代理的目标的类名是需要自己复写getClass方法的。
代理的运作其实还是用到了反射的原理。
3). defineClass方法将一个byte数组转换为Class类的实例。这种新定义的类的实例可以使用Class.newInstance来创建
protected Class<?> defineClass(Stringname,byte[] b, int off, int len) 将一个byte数组转换为Class类的实例。
protected Class<?> defineClass(Stringname,byte[] b, int off, int len, ProtectionDomainprotectionDomain)使用可选的 ProtectionDomain将一个byte数组转换为Class类的实例。
protected Class<?> defineClass(Stringname,ByteBuffer b, ProtectionDomain protectionDomain) 使用可选的ProtectionDomain将ByteBuffer转换为Class类的实例。
4). ClassLoader类
protected ClassLoader() 创建一个新的类加载器,将该加载器作为父类加载器。
protected ClassLoader(ClassLoader parent) 使用指定的、用于委托操作的父类加载器创建新的类加载器。
------- android培训、java培训、期待与您交流! ----------