• 动态代理和CGlib


    静态代理:静态代理的类也需要实现接口interface1,还要创建一个实现接口interface1的其他类class1,并且在静态代理类重写的方法中调用class1重写的方法。操作太多冗余。不好

    动态代理:

      jdk动态代理的实现:java.lang.reflect.Proxy,java.lang.reflect.InvocationHandler、Method

        在运行时动态创建代理对象,newProxyInstance方法最重要。,指明了将要代理的类的加载器、业务接口类、以及代理类要执行动作的调用处理器(InvokeHandler)

        

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

    接口:

    public interface BookFacade {
        public void addBook();
        public void deleteBook();
    }

    业务类:

    public class BookFacadeImpl implements BookFacade {
        @Override
        public void addBook() {
            System.out.println("add book");
    
        }
    
        @Override
        public void deleteBook() {
            System.out.println("delete book");
    
        }
    }

    动态代理类:

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class BookFacadeProxy implements InvocationHandler {
    
        private Object target;
        public Object bind(Object target){
            this.target=target;
            return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            Object result = null;
            System.out.println("proxy start");
            System.out.println("method name..."+method.getName());
            result=method.invoke(target,args);
            System.out.println("method end...");
            return  result;
        }
    }

    测试类:

    public class TestProxy {
        public static void main(String[] args) {
            BookFacadeProxy proxy=new BookFacadeProxy();
            BookFacade bookProxy= (BookFacade) proxy.bind(new BookFacadeImpl());
            bookProxy.addBook();
            bookProxy.deleteBook();
        }
    }

    jdk的proxy总结:

      (1)Interface :对于jdk proxy,业务类是需要一个Interface的

      (2)Proxy,是动态产生的,这个类在调用Proxy.newProxyInstance之后会产生一个Proxy类的实例。实际上这个Proxy类是存在的,不仅仅是类的实例。

      (3)Method:对于业务委托类的每个方法,现在Proxy类里面都不用静态显示出来。

      (4)InvocationHandler:这个类在业务委托类执行时,先调用invoke方法。invoke再执行对应的代理操作,可以实现对业务方法的再包装。

    CGLib:jdk动态代理机制只能代理实现了接口的类,而不能实现接口的累就不能实现jdk的动态代理,cglib是针对类来实现代理的,他的原理是对制定目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的继承,所以不能对final修饰的类进行代理。

    业务类:

    同前面的那个接口

    并没有实现接口

    public class BookFacadeImpl1 {
       public void addBook(){
           System.out.println("this is addBook in BookFacadeImpl1");
       }
    }

    代理:

    import org.mockito.cglib.proxy.Enhancer;
    import org.mockito.cglib.proxy.MethodInterceptor;
    import org.mockito.cglib.proxy.MethodProxy;
    
    import java.lang.reflect.Method;
    
    public class BookFacadeCglib implements MethodInterceptor {
        private Object target;

    //创建代理对象
    public Object getInstance(Object target){ this.target=target; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.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("Transaction start"); proxy.invokeSuper(obj,args); System.out.println("transaction end"); return null; } }

    测试:

    public class TestCglib {
    
        public static void main(String[] args) {
            BookFacadeCglib cglib = new BookFacadeCglib();
            BookFacadeImpl1 bookCglib = (BookFacadeImpl1) cglib.getInstance(new BookFacadeImpl1());
            bookCglib.addBook();
        }
    }
  • 相关阅读:
    搭建wamp环境,数据库基础知识
    练习题:选择器和选择好友
    例子:滑动效果
    TCPDump
    内存
    Cache和Buffer的区别(转载)
    经典问题回忆
    history
    DNS
    bc的用法
  • 原文地址:https://www.cnblogs.com/zhy-study/p/9392819.html
Copyright © 2020-2023  润新知