实现动态代理有二种方法:1.使用 jdk 提供的方式  要求委托类必须实现接口

                                2.继承委托类

public class UserAction {
  private UserDao userDao = UserDaoFac.newUserDao();
  public void add(){
    System.out.println("=====UserAction=====");
    //userDao.add();
    userDao.add("sss");
  }
  public static void main(String[] args) {
    new UserAction().add();
  }
}

public interface UserDao {
  public void add(String s);
  public void add();
}

public class UserDaoImpl implements UserDao {
  @Override
  public void add(String s) {
    System.out.println("=======UserDao========"+s);
  }
  @Override
  public void add() {
    System.out.println("=======UserDao========");
  }
}

/**
* 动态代理:
* 1.jdk 提供的方式 要求委托类必须实现接口
* @author Administrator
*
*/
public class UserDaoFac {       通过jdk的方式实现动态代理
  public static UserDao newUserDao(){
  /**
  * 三个参数
  * 1.类加载器
  * 2.InvocationHandle 代理类 要写的逻辑
  *    public class $Proxy0 implements UserDao{
  *     private InvocationHandle handler;
  *     public void add(){
  *        Method method = UserDao.class.getDeclaredMethod("add");
  *       handle.invoke(this,method,args);
  *      }
  *   }
  */

    return (UserDao)Proxy.newProxyInstance(UserDaoFac.class.getClassLoader(), new Class[]{UserDao.class}, new InvocationHandler() {
  /**
  * 三个参数
  * 1:代理类对象
  * 2:委托类 的那个方法对应的映射方法
  * 3:委托类的那个方法的实参
  *
  */
      @Override
      public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        method.invoke(new UserDaoImpl());
        System.out.println("完成了日志操作");
        return null;
      }
    });
  }
}

/**
* 动态代理:
* 1.jdk 提供的方式 要求委托类必须实现接口
* 2.继承委托类
* @author Administrator
*
*/
public class UserDaoFac2 {     // 通过继承来实现动态代理(使用继承来实现动态代理必须导入三个jar包asm.jar, cglib-2.1.3.jar,commons-logging-1.0.4.jar)   了解   

public static UserDao newUserDao(){
  Enhancer eh = new Enhancer();
  eh.setSuperclass(UserDaoImpl.class);
  eh.setCallback(new MethodInterceptor() {
  /**
  * 四个参数
  * 1.代理类对象
  * 2.委托类的那个方法对应的映射方法
  * 3.委托类的那个方法的实参
  * 4.委托类的被调用的方法对象
  */
    @Override
    public Object intercept(Object arg0, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
      System.out.println("==============");
      System.out.println(arg0.getClass());
      System.out.println(Arrays.toString(args));
      method.invoke(new UserDaoImpl(), args);
      System.out.println("完成了日志操作!!!");
      System.out.println("====================");
      return null;
    }
  });
  return (UserDao)eh.create();
  }
}