什么是(jdk)动态代理?
代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
而(jdk)动态代理是在反射基础上进行的动态实现的代理。(当然还有一些基于其他的: ASM(一个短小精悍的字节码操作框架)、cglib(基于 ASM))
java动态代理类
Java动态代理类位于java.lang.reflect包
//Interface InvocationHandler:该接口只有一个invoke方法//第一个参数obj一般是指代理类,method是被代理的方法,args为该方法的参数数组public objectinvoke(Object obj,Method method,Object[] args)//动态代理类:Proxy//获得一个代理类,其中loader是类装载器,interfaces是真实类所拥有的全部接口的数组。staticClass getProxyClass(ClassLoaderloader,Class[] interfaces)//返回代理类的一个实例,返回后的代理类可以当作被代理类使用(可使用被代理类的在Subject接口中声明过的方法)staticObjectnewProxyInstance(ClassLoaderloader,Class[] interfaces,InvocationHandler h)
jdk动态代理使用
- 创建被代理的类以及接口
/**
* 需要动态代理的接口
*/publicinterfaceJob{/**
* run....
* @param name
* @return
*/publicStringrunJob(String s);}
/**
* 实际对象
*/publicclassRealJobimplementsJob{/**
* run...
* @param name
* @return
*/publicStringrunJob(String s){return"run..... "+ s;}}
- .创建一个实现接口InvocationHandler的类,它必须实现invoke方法
/**
* 调用处理器实现类
* 每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象
*/publicclassInvocationHandlerImplimplementsInvocationHandler{/**
* 这个就是我们要代理的真实对象
*/privateObject job;/**
* 构造方法,给我们要代理的真实对象赋初值
*
* @param subject
*/publicInvocationHandlerImpl(Object job){this.job= job;}/**
* 该方法负责集中处理动态代理类上的所有方法调用。
* 调用处理器根据这三个参数进行预处理或分派到委托类实例上反射执行
*
* @param proxy 代理类实例
* @param method 被调用的方法对象
* @param args 调用参数
* @return
* @throws Throwable
*/publicObjectinvoke(Object proxy,Method method,Object[] args)throwsThrowable{//在代理真实对象前我们可以添加一些自己的操作System.out.println("我要准备run了");System.out.println("Method:"+ method);//当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用Object returnValue= method.invoke(subject, args);//在代理真实对象后我们也可以添加一些自己的操作System.out.println("我已经run完了");return returnValue;}}
- 通过proxy进行实现
/**
* 动态代理演示
*/publicclassDynamicProxyTest{publicstaticvoidmain(String[] args){//代理的真实对象Job realJob=newRealJob();/**
* InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
* 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用.
* 即:要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法
*/InvocationHandler handler=newInvocationHandlerImpl(realJob);ClassLoader loader= realJob.getClass().getClassLoader();Class[] interfaces= realJob.getClass().getInterfaces();/**
* 该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
*/Job job=(Job)Proxy.newProxyInstance(loader, interfaces, handler);System.out.println("动态代理对象的类型:"+job.getClass().getName());String runString= job.run("april");System.out.println(runString);}}