需要动态代理的接口:
public interface Jdk { public void say(); }
需要代理的实际对象:
1.
public class JdkImpl implements Jdk { @Override public void say() { System.out.println("hello ...."); } }
2.
public class JdkImpl2 implements Jdk { @Override public void say() { System.out.println("bye ...."); } }
调用处理器实现类
每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象
public class JdkProxy implements InvocationHandler { //这个就是我们要代理的真实对象 private Object object; //构造方法,给我们要代理的真实对象赋初值 public JdkProxy(Object object){ this.object = object; } /** * * @param proxy 代理对象 * @param method 代理对象调用的方法 * @param args 调用方法中的参数 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("Before....."); //当代理对象调用真实对象的方法时,其会自动的跳转到代理对象关联的handler对象的invoke方法来进行调用 result = method.invoke(object,args); System.out.println("After....."); return result; } }
测试:
public class Test { public static void main(String[] args) { //代理的真实对象 JdkImpl jdkImpl = new JdkImpl(); /** * InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到 * 委托类的分派转发其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用. * 即:要代理哪个真实对象,就将该对象传进去,最后是通过该真实对象来调用其方法 */ InvocationHandler handler = new JdkProxy(jdkImpl); //该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例 Jdk jdk = (Jdk) Proxy.newProxyInstance( JdkImpl.class.getClassLoader(),//类加载器 JdkImpl.class.getInterfaces(),//用来代理的接口 handler); //InvocationHandler 对象 jdk.say(); //------------------------------------###---------------------------------- JdkImpl2 jdkImpl2 = new JdkImpl2(); InvocationHandler handler2 = new JdkProxy(jdkImpl2); Jdk jdk2 = (Jdk) Proxy.newProxyInstance( JdkImpl2.class.getClassLoader(), JdkImpl2.class.getInterfaces(), handler2); jdk2.say(); } /** * JDK动态代理技术的实现是必须要一个接口才行的,所以JDK动态代理的优缺点也非常明显: * * 优点: * * 不需要为真实主题写一个形式上完全一样的封装类,减少维护成本; * 可以在运行时制定代理类的执行逻辑,提升系统的灵活性; * * 缺点: * * 需要代理的实际对象,必须实现需要动态代理的接口,如果 没有接口 或 没实现接口 就不能生成代理对象 */ }