在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。没有接口的情况下可以使用更强大的cglib进行代理。

Proxy类中的方法创建动态代理类对象

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

最终会调用InvocationHandler的方法

Object invoke(Object proxy,Method method,Object[] args)

代码:


    // 定义接口
    public interface FooDao {
        void doSomething();
    }

    // 定义实现
    static class FooDaoImpl implements FooDao{
        @Override
        public void doSomething() {
            System.out.println("Impl....");
        }
    }

    // 代理处理器
    static class FooInvocationHandler implements InvocationHandler{

        // 代理的对象
        Object target;

        public FooInvocationHandler(Object target) {
            this.target = target;
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("before");
            Object result = method.invoke(target, args);// 执行代理服务的方法
            System.out.println("after");
            return result; // 返回的是代理对象
        }
    }

    public static void main(String[] args) {
        // 原服务
        FooDao fooDao = new FooDaoImpl();
        // 代理服务
        FooDao proxyDao = (FooDao) Proxy.newProxyInstance(fooDao.getClass().getClassLoader(), fooDao.getClass().getInterfaces(), new FooInvocationHandler(fooDao));
        // 打印原服务类名
        System.out.println(fooDao.getClass().getName());
        // 原服务输出
        fooDao.doSomething();
        System.out.println("-------");
        // 打印代理服务类名
        System.out.println(proxyDao.getClass().getName());
        // 代理服务执行 
        proxyDao.doSomething();
        System.out.println("-------");
    }

输出:

cn.xxxxx.xxxxx.xxxxx$FooDaoImpl
Impl....
-------
com.sun.proxy.$Proxy0
before
Impl....
after
-------