zoukankan      html  css  js  c++  java
  • 切面编程(一)

    一、切面编程概述

      Aspect Oriented Programming(AOP),面向切面编程,是一个比较热门的话题。AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。

      什么是代理:代理(Proxy)是一种设计模式, 提供了对目标对象另外的访问方式,即通过代理访问目标对象。这样可以在目标对象实现的基础上,增强额外的功能操作。(扩展目标对象的功能)

    二、JDK静态代理和动态代理

      JDK代理内容详细见 http://www.cnblogs.com/jiyukai/p/6958744.html

    三、cglib代理

        Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。

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

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

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

       Cglib子类代理Demo实现 

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

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

      (3)代理的类不能为final修饰;

      (4)如果目标对象的方法为final/static, 那么将不会被拦截。

       具体实现代码

       1.业务实现类,即将被代理的目标对象

    package com.jyk.spring.cglib;
    
    public class UserDao {
    
        public void cglibTest()
        {
            System.out.println("cglib代理执行方法");
        }
    }

      2. cglib代理工厂,必须实现MethodInterceptor接口

    package com.jyk.spring.cglib;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    /*
     * cglib子类代理工厂
     * 必须实现MethodInterceptor接口
     * 对UserDao在内存中动态构建一个子类对象
     */
    public class UserCglibProxy implements MethodInterceptor{
    
        //维护目标对象
        private Object target;
        
        public UserCglibProxy(Object target)
        {
            this.target = target;
        }
        
        /*
         * 给目标对象创建代理对象
         */
        public Object getProxyInstance()
        {
            //1、初始化工具类
            Enhancer en = new Enhancer();
            
            //2、设置父类
            en.setSuperclass(target.getClass());
            
            //3、设置回调函数,触发intercept方法
            en.setCallback(this);
            
            //4、创建子类(即代理对象)
            return en.create();
        }
        
        @Override
        public Object intercept(Object obj, Method method, Object[] arg2,
                MethodProxy proxy) throws Throwable {
            
            System.out.println("执行开始");
            
            //执行目标对象的方法
            Object returnValue = method.invoke(target, arg2);
            
            System.out.println("执行结束");
            return returnValue;
        }
    
    }

      3.执行结果,由打印出来的对象可以看到proxy已经不是原有UserDao,而是经过cglib代理生成的代理对象

      

      结论:在SpringAOP编程中,

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

  • 相关阅读:
    RE最全面的正则表达式----字符验证
    Ajax tips(my_jquery_function.js)
    Python 分布式执行测试用例
    Python black + flake8 自动化规范代码
    JavaScript学习笔记-ES5
    pytest-assume 测试用例某一断言失败继续执行后面的代码
    pytest常用命令行
    [pretty_errors] Prettifies Python exception output to make it legible
    requests-html
    Python 类 继承与重写
  • 原文地址:https://www.cnblogs.com/jiyukai/p/9385268.html
Copyright © 2011-2022 走看看