WHWW之代理模式(2)-动态代理
What:什么叫动态代理?
代理类并不是在Java代码中定义的,而是在运行时根据我们在Java代码中的“指示”动态生成的,或者说一个代理类是在程序运行时才获取到目标对象的代理。动态代理又称jdk代理。
How:怎么实现动态代理?
/** * 抽象角色接口 */ public interface Hello { /** * 打招呼 */ void sayHello(); }
/** * 目标对象角色类 */ public class RealHello implements Hello { /** * 实现接口的方法 */ @Override public void sayHello() { System.out.println("你好"); } }
/** * 动态代理类 */ public class DynamicProxy implements InvocationHandler { //目标对象 private Object target; public DynamicProxy(Object target) { this.target = target; } /** * 代理实现方法 * @param proxy * @param method * @param args * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { before(); Object result=method.invoke(target,args); after(); return result; } /** * 在实现方法前可以做的事情 */ public void before(){ System.out.println("摘下耳机"); } /** * 在实现方法后做的事情 */ public void after(){ System.out.println("戴上耳机"); } }
/** * 动态代理测试 */ public class DynamicProxyTest { public static void main(String[] args) { Hello hello=new RealHello(); hello.sayHello(); System.out.println("====================="); System.out.println("动态代理:"); DynamicProxy dynamicProxy=new DynamicProxy(hello); // 通过反射加载hello,获取hello接口的方法,生成动态代理 Hello helloProxy= (Hello) Proxy.newProxyInstance(hello.getClass().getClassLoader(),hello.getClass().getInterfaces(),dynamicProxy); helloProxy.sayHello(); } }
控制台输出:
你好
=====================
动态代理:
摘下耳机
你好
戴上耳机
Why:为什么要使用动态代理?
虽然静态代理可以实现我们某些需求,但其缺点也是让我们不想用它的原因,可以看《WHWW之代理模式(1)-静态代理》。因为程序员是追求高效的,动态代理是利用Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类。
Where:哪些地方有用到动态代理呢?
动态代理让我们在不直接访问某些对象的情况下,通过代理机制也可以访问被代理对象的方法,所以可以应用在很多地方。比如RPC框架,Spring AOP机制。
注:虽然代理对象(DynamicProxy)不需要实现接口,但是目标对象(RealHello)一定要实现接口(Hello),否则就不能用动态代理。