zoukankan      html  css  js  c++  java
  • Java基础-CGLIB动态代理

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

      且CGLib构造的代理类是目标类的一个子类(需要实现MethodInterceptor接口等)

      

      CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑

    示例 

    BookFacadeCglib.java 

    package net.battier.dao;  
      
    public interface BookFacade {  
        public void addBook();  
    }  

    BookCadeImpl1.java 

    package net.battier.dao.impl;  
      
    /** 
     * 这个是没有实现接口的实现类 
     *  
     * @author student 
     *  
     */  
    public class BookFacadeImpl1 {  
        public void addBook() {  
            System.out.println("增加图书的普通方法...");  
        }  
    }  

    BookFacadeProxy.java 

    package net.battier.proxy;  
      
    import java.lang.reflect.Method;  
      
    import net.sf.cglib.proxy.Enhancer;  
    import net.sf.cglib.proxy.MethodInterceptor;  
    import net.sf.cglib.proxy.MethodProxy;  
      
    /** 
     * 使用cglib动态代理 
     *  
     * @author student 
     *  
     */  
    public class BookFacadeCglib implements MethodInterceptor {  
        private Object target;  
      
        /** 
         * 创建代理对象 
         *  
         * @param target 
         * @return 
         */  
        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("事物开始");  
            proxy.invokeSuper(obj, args);  
            System.out.println("事物结束");  
            return null;  
      
      
        }  
      
    }  

    TestCglib.java 

    package net.battier.test;  
      
    import net.battier.dao.impl.BookFacadeImpl1;  
    import net.battier.proxy.BookFacadeCglib;  
      
    public class TestCglib {  
          
        public static void main(String[] args) {  
            BookFacadeCglib cglib=new BookFacadeCglib();  
            BookFacadeImpl1 bookCglib=(BookFacadeImpl1)cglib.getInstance(new BookFacadeImpl1());  
            bookCglib.addBook();  
        }  
    }  

     注:

     CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理

  • 相关阅读:
    array_map()与array_shift()搭配使用 PK array_column()函数
    Educational Codeforces Round 8 D. Magic Numbers
    hdu 1171 Big Event in HDU
    hdu 2844 poj 1742 Coins
    hdu 3591 The trouble of Xiaoqian
    hdu 2079 选课时间
    hdu 2191 珍惜现在,感恩生活 多重背包入门题
    hdu 5429 Geometric Progression 高精度浮点数(java版本)
    【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
    hdu::1002 A + B Problem II
  • 原文地址:https://www.cnblogs.com/hwaggLee/p/4501911.html
Copyright © 2011-2022 走看看