静态代理要为每个目标类创建一个代理类,当需要代理的对象太多,那么代理类也变得很多。同时代理类违背了可重复代理只写一次的原则。jdk给我们提供了动态代理。其原理图如下:
Jdk的动态要求目标对象必须实现接口,因为它创建代理对象的时候是根据接口创建的。如果不实现接口,jdk无法给目标对象创建代理对象。被代理对象可以可以实现多个接口,创建代理时指定创建某个接口的代理对象就可以调用该接口定义的方法了。
package com.wl.jdk.dynamicproxy; public interface Service { public void sayHello(String content); }
package com.wl.jdk.dynamicproxy; public interface UserService { public void delUser(String userId); }
/** * 实现这2个接口的目标对象:UserServiceImpl.java */ public class UserServiceImpl implements UserService, Service{ public void sayHello(String content) { System.out.println("你好:" + content); } public void delUser(String userId) { System.out.println("UserServiceImpl delUser userId->>"+userId); } }
package com.wl.jdk.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 生成代理对象的的类 */ public class ProxyFactory implements InvocationHandler{ private Object targetObj; public Object newInstance(Object targetObj){ this.targetObj = targetObj; Class targertClass = targetObj.getClass(); return Proxy.newProxyInstance(targertClass.getClassLoader(), targertClass.getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object ret = null; // System.out.println("开始调用方法:" + method.getName()); // for(int i = 0; i < args.length; i ++){ // System.out.println("调用方法:" + method.getName() + ",参数为:" + args[i]); // } // System.out.println("------------------------------------------"); ret = method.invoke(targetObj, args); return ret; } }
package com.wl.jdk.dynamicproxy; /** * 使用工厂类生成目标类的代理 */ public class Client { public static void main(String[] args) { Service service = (Service)new ProxyFactory().newInstance(new UserServiceImpl()); UserService userService = (UserService)new ProxyFactory().newInstance(new UserServiceImpl()); userService.delUser("001"); String content = "早上好!"; service.sayHello(content); } }