AOP底层使用动态代理
(1)有两种情况动态代理
第一种:有接口情况,使用JDK动态代理
*创建接口实现类代理对象,增强类的方法
第二种:没有接口情况,使用CGLIB动态代理
*创建子类的代理对象,增强类的方法

JDK动态代理代码实现
1.使用Proxy类里面方法创建代理对象
Class Proxy
java.lang.Object
java.lang.reflect.Proxy
2.调用newProxyInstance方法
static Object   newProxyInstance(ClassLoader loader, 类<?>[] interfaces, InvocationHandler h)
返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
方法有三个参数:
1).类加载器
2).增强方法所在的类
3).实现InvocationHandler接口,创建代理对象,写增强部分代码
3.JDK动态代理代码
1)创建接口,定义方法
public interface UserDao {
    public int add(int a,int b);
    public String update(String id);
}
2)创建接口实现类,实现方法
public class UserDaoImpl implements UserDao{
    @Override
    public int add(int a, int b) {
        System.out.println("add方法执行了。。。。");
        return a+b;
    }
    @Override
    public String update(String id) {
        System.out.println("update方法执行了。。。。");
        return id;
    }
}
3)使用Proxy类,创建接口代理对象
//创建代理对象代码
class UserDaoProxy implements InvocationHandler{
    //通过构造方法,将需要代理的对象传递进来
    //    有参构造传递
    //可以直接 传递 UserDaoImpl对象,但为了通用,使用Object
    private Object object;
    public UserDaoProxy(Object object){
        this.object = object;
    }
    //增强的代理逻辑
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //可以根据获取的对象,代码名称判断 是否增强
        //方法之前
        System.out.println("方法之前执行。。。。。"    + method.getName() + "  传递的参数:"+ Arrays.toString(args));
        //执行方法-被增强的方法
        Object res = method.invoke(object, args);
        //方法之后
        System.out.println("方法之后执行1。。。。。"    + method.getName() + "  传递的参数:"+ Arrays.toString(args));
        System.out.println("方法之后执行2。。。。。"    + method.getName() + "  返回值:"+ res);
        System.out.println("方法之后执行3。。。。。"    + method.getName() + "  增强的对象:"+ object);
        return res;
    }
}
public class JDKProxy {
    public static void main(String[] args) {
        //创建接口实现类代理对象
        Class[] interfases = {UserDao.class};
        //1.InvocationHandler内部类的实现方式
//        Object o = Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfases, new InvocationHandler() {
//            @Override
//            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//                return null;
//            }
//        });
//        2.InvocationHandler外部实现
        UserDao userDao = new UserDaoImpl();
        UserDao dao =
                (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfases,new UserDaoProxy(userDao));
        int add = dao.add(2, 3);
        System.out.println("相加的结果:"+add);
        System.out.println("=============================================");
        String update = dao.update("30");
        System.out.println("更新的结果:"+update);
    }
}
4)代码执行结果:
方法之前执行。。。。。add  传递的参数:[2, 3]
add方法执行了。。。。
方法之后执行1。。。。。add  传递的参数:[2, 3]
方法之后执行2。。。。。add  返回值:5
方法之后执行3。。。。。add  增强的对象:com.spring5.UserDaoImpl@355da254
相加的结果:5
=============================================
方法之前执行。。。。。update  传递的参数:[30]
update方法执行了。。。。
方法之后执行1。。。。。update  传递的参数:[30]
方法之后执行2。。。。。update  返回值:30
方法之后执行3。。。。。update  增强的对象:com.spring5.UserDaoImpl@355da254
更新的结果:30