动态代理

一、什么是动态代理

        1.代理对象,不需要实现接口
        2.代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象(需要我们指定创建代理对象/目标对象实现的接口的类型)
        3.动态代理也叫做:JDK代理,接口代理

二、JDK动态代理

  1)原理:是根据类加载器和接口创建代理类(此代理类是接口的实现类,所以必须使用接口 面向接口生成代理,位于java.lang.reflect包下) 
  2)实现方式: 
        a. 通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…); 
        b. 通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…}); 
        c.  通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class}); 
        d. 通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));

  
        public class InvocationHandlerImpl implements InvocationHandler {
                  private Object target;// 这其实业务实现类对象,用来调用具体的业务方法

                  // 通过构造函数传入目标对象
                  public InvocationHandlerImpl(Object target){
                      this.target = target;
                  }
       @Override
       public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object result = null;
                System.out.println("调用开始处理");
                method.invoke(target, args);
                System.out.println("调用结束处理");
                return result;
      }

      public static void main(String[] args) {
              // 被代理对象
             IUserDao userDao = new UserDao();
             InvocationHandlerImpl invocationHandlerImpl = new InvocationHandlerImpl(userDao);
             ClassLoader loader = userDao.getClass().getClassLoader();
             Class<?>[] interfaces = userDao.getClass().getInterfaces();
             // 主要装载器、一组接口及调用处理动态代理实例
             IUserDao newProxyInstance = (IUserDao) Proxy.newProxyInstance(loader, interfaces, invocationHandlerImpl);
             newProxyInstance.save();
      }
    }

三、CGLIB动态代理

        使用cglib[Code Generation Library]实现动态代理,并不要求委托类必须实现接口,底层采用asm字节码生成框架生成代理类的字节码


        public class CglibProxy implements MethodInterceptor {

                  private Object targetObject;

                  // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
                  public Object getInstance(Object target){
                  // 设置需要创建子类的类
                  this.targetObject = target;
                  Enhancer enhancer = new Enhancer();
                  enhancer.setSuperclass(target.getClass());
                  enhancer.setCallback(this);
                  return enhancer.create();
            }

                @Override
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
                      System.out.println("开启事物");
                      Object result = proxy.invoke(targetObject, args);
                      System.out.println("关闭事物");
                      return result;
                  }

               public static void main(String[] args) {
                      CglibProxy cglibProxy = new CglibProxy();
                      PersonDao personDao =(PersonDao)cglibProxy.getInstance(new PersonDao());
                      personDao.save();
               }

           }
posted @ 2020-11-30 19:27  jock_javaEE  阅读(157)  评论(0编辑  收藏  举报