JDK动态代理主要是Proxy和InvocationHandler的组合应用
JDK动态代理是基于接口实现的,所以被代理对象必须要实现某个接口。
即
接口+实现类(被代理对象)+InvocationHandler的实现类(完成被代理对象的代理动作)+Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)(生成代理对象),使用生成的代理对象去执行方法时,就会走到代理对象添加的方法中。
代码示例:
接口类:
package com.wdr.practice.jdkproxy.intf; public interface PeopleInterface { void say(); }
接口实现类:
package com.wdr.practice.jdkproxy.impl; import com.wdr.practice.jdkproxy.intf.PeopleInterface; public class Adult implements PeopleInterface { @Override public void say() { System.out.println("i am an Audlt"); } }
handler:
package com.wdr.practice.jdkproxy.handler; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class PeopleInvocationHandler implements InvocationHandler { private Object targetObj; public Object getTargetObj() { return targetObj; } public void setTargetObj(Object targetObj) { this.targetObj = targetObj; } private void beforeMethod(){ System.out.println("openning mic..."); } private void afterMethod(){ System.out.println("closing mic..."); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { beforeMethod(); method.invoke(targetObj, args); afterMethod(); return null; } }
调用:
package com.wdr.practice.jdkproxy.client; import com.wdr.practice.jdkproxy.handler.PeopleInvocationHandler; import com.wdr.practice.jdkproxy.impl.Adult; import com.wdr.practice.jdkproxy.intf.PeopleInterface; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { // 生成接口实现实例 PeopleInterface adult = new Adult(); // 生成handler实例 PeopleInvocationHandler peopleInvocationHandler = new PeopleInvocationHandler(); // 设置被代理对象 peopleInvocationHandler.setTargetObj(adult); // 获取代理对象实例 PeopleInterface adultProxy = (PeopleInterface) Proxy.newProxyInstance(adult.getClass().getClassLoader(), adult.getClass().getInterfaces(), peopleInvocationHandler); adultProxy.say(); } }
执行结果:
其他:
这里只记录了jdk动态代理的用法,具体原理没有深究,比如:
(PeopleInterface) Proxy.newProxyInstance(adult.getClass().getClassLoader(), adult.getClass().getInterfaces(), peopleInvocationHandler); 这一步具体是干了什么
InvocationHandler里面的beforeMethod和afterMethod写的比较简单,如果需要根据不同方法打印不同内容,则可能需要把method传过去,这里就不写那么多了,框架有了,插座还能安不上的吗