• 设计模式(三) cglib代理


    1.1、cglib代理,也可也叫子类代理

      

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

                注意事项:

                    l JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口。如果想代理没有实现接口的类,就可以使用CGLIB实现。

                    l   CGLIB是一个强大的高性能的代码生成包,它可以在运行期扩展Java类与实现Java接口。它广泛的被许多AOP的框架使用,例如Spring AOPdynaop,为他们提供方法的interception(拦截)。

                    l  CGLIB包的底层是通过使用一个小而快的字节码处理框架ASM,来转换字节码并生成新的类。不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉。(具体可自行查找翻阅)

                   

             

     代码实现如下:(需要引入cglib – jar文件

    UserDao:目标对象

    public class UserDao  { //目标对象
    
        public void save() {
            System.out.println("保存用户");
        }
    }
    ProxyFactory:代理工厂(必须实现MethodInterceptor,重写intercept方法)
    public class ProxyFactory implements MethodInterceptor{
    
        //维护目标对象
        private Object target;
    
        public ProxyFactory(Object target) {
            this.target = target;
        }
        //给目标对象创建代理对象
        public Object getProxyInstance(){
            //工具类
            Enhancer enhancer = new Enhancer();
            //设置父类
            enhancer.setSuperclass(target.getClass());
            //设置回调方法
            enhancer.setCallback(this);
            //创建子类对象
            return enhancer.create();
    
        }
        //执行父类方法的时候调用的拦截器,在此添加增强父类方法的行为
        @Override
        public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("日志打印开始");
            Object obj  = methodProxy.invokeSuper(o,args);
            System.out.println("日志打印结束");
            return obj;
        }
    }

    main:测试类

    public class Main {
    
        public static void main(String[] args) {
    
            UserDao target = new UserDao();
    
            UserDao proxyFactory = (UserDao) new ProxyFactory(target).getProxyInstance();
    
            proxyFactory.save();
    
    
        }
    }

    结果打印:

    使用总结:

        

          Cglib子类代理:

              1) 需要引入cglib – jar文件, 但是spring的核心包中已经包括了cglib功能,所以直接引入spring-core-*.jar即可。

              2)引入功能包后,就可以在内存中动态构建子类

              3)代理的类不能为final, 否则报错。

              4) 目标对象的方法如果为final/static, 那么就不会被拦截,即不会执行目标对象额外的业务方法。

          在SpringAOP编程中,

                    如果加入容器的目标对象有实现接口,用JDK代理;

                    如果目标对象没有实现接口,用Cglib代理;

  • 相关阅读:
    串行化数据读取类(WebService下DataSet的高性能替代类)源代码
    如何在Access2007中打开加密的Access2003数据库
    业务流程不是需求(ZT)
    XML文件的DOCTYPE定义(转)
    别让Hibernate偷走了您的身份(转)
    有关Struts标签<html:cancel>使用的一点提示
    Silverlight下实现Windows8风格的进度条
    DotNetMock单元测试的利器
    进入ubuntu终端的快捷键
    花生壳域名建站,内网能访问,外网不能访问的解决办法
  • 原文地址:https://www.cnblogs.com/yuanchaoyong/p/6415547.html
Copyright © 2020-2023  润新知