简介

就是能够在运行时动态编译执行的代理功能模块,由于是动态执行,因此可以根据程序策略或状态动态的生成对应的类和实例。

InvocationHandler,是代理实例的调用处理程序 实现的接口
invoke,直接的理解为:当调用被代理对象的某个方法时,实际上会在该接口的实现类上调用invoke方法。也就是说,invoke方法就是代替原来执行的方法。

  1. public interface InvocationHandler {
  2. public Object invoke(Object proxy, Method method, Object[] args)
  3. throws Throwable;
  4. }

Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
此方法会生成代理类的java文件,并编译生成.claas文件,动过ClassLoader创建该代理类

20180930105231807.png

20180930105331589.png

JDK的动态代理例子

一个接口

  1. public interface UserDao {
  2. void save(User user);
  3. }

接口的实现类

  1. public class UserDaoImpl implements UserDao{
  2. @Override
  3. public void save(User user) {
  4. System.out.println("save");
  5. }

InvocationHandler的实现类,也就是调用处理类,调用处理程序

  1. public class UserDaoProxyHandler implements InvocationHandler{
  2. private UserDao UserDao;
  3. public Handler(UserDao ud) {
  4. this.UserDao = ud;
  5. }
  6. @Override
  7. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  8. System.out.println("start");//前置处理
  9. method.invoke(UserDao, args);
  10. System.out.println("end");//后置处理
  11. return "done";
  12. }

测试代理使用类

  1. public class TestProxy {
  2. public static void main(String [] args){
  3. UserDao ud = new UserDaoImpl();
  4. UserDaoProxyHandler handler = new UserDaoProxyHandler(ud);//创建调用处理类
  5. //得到代理类实例
  6. UserDao proxy = (UserDao) Proxy.newProxyInstance(UserDao.class.getClassLoader(), new Class[]{UserDao.class}, handler);
  7. proxy.save(new User());//调用代理类的方法
  8. }
  9. }

创建流程图
20170927034846990.png

调用时序图

动态代理 - 图4

参考文档
底层动态生成代理类和编译过程
JDK动态代理图解