一、AOP编程(面向切面编程)

  AOP的本质是代理。

  1、静态代理设计模式

    概念:通过代理类为原始类增加额外功能。

       代理类 = 原始类 + 额外功能 +实现原始类的相同接口。

    优点:避免原始类因为额外功能频繁被修改,从而使代码更加利于维护。

    缺点:a、代理类数量过多,不利于管理项目。

       b、额外功能代码冗余。

       c、替换代理的额外功能很麻烦。

  2、Spring的动态代理设计模式(AOP)

    a、导入jar包:aopallaince.jar和aspectjwave.jar

    b、创建原始对象

      原始对象只有核心功能,没有额外功能。

    c、创建额外功能

      按照需求实现以下接口(均实现了父接口Advice):

      (1)MethodBeforeAdvice

//额外功能在原始方法之前运行
public class MyInterceptor implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { //参数:method--原始方法,args--原始方法的参数,target--原始对象
//添加额外功能 method.invoke(args, target); } }

      (2)AfterReturningAdvice

//额外功能在原始方法之后运行
public class MyInterceptor implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object ret, Method method, Object[] args, Object target) throws Throwable {

        method.invoke(ret, args);
        //ret--原始方法的返回值,参数:method--原始方法,args--原始方法的参数,target--原始对象
//添加额外功能 } }

      (3)MethodInterceptor

//原始方法之前之后都有额外功能
public class Intercepter implements MethodInterceptor { @Override public Object invoke(MethodInvocation mi) throws Throwable { //参数:mi--原始方法
//添加额外功能 Object obj = mi.proceed(); //添加额外功能
     //返回值Object:原始方法的返回值 return obj; } }

      (4)ThrowsAdvice

        额外功能在原始方法抛出异常时执行。

    d、定义切入点pointcut

      设置额外功能加入的位置。

      切入点函数execution():

<aop:pointcut id="pc" expression="execution(* *(..))">

      (1)方法切入点

        execution()

        切入点表达式  * *(..)

        第一个*表示方法的返回值,第二个*表示方法名,(..)表示方法的参数。eg:

        * login(String) 表示名叫login的只有一个字符串参数的方法。      

      (2)类切入点

        execution()

        切入点表达式  * *.类名.*(..)

        第一个*表示方法的返回值,第二个*表示该类的包名,第二个*表示方法名,(..)表示方法的参数。eg:

        * *.UserServiceImpl.*(..) 表示UserServiceImpl类。

      (3)包切入点

        execution()

        切入点表达式 * 包名.*.*(..)支持当前包中的类,不包括包中子类,* 包名..*.*(..)支持包中子类

        第一个*表示方法的返回值,第二个*表示类名,第三个*表示方法名,(..)表示方法的参数。

      切入点函数args():

<!--此切入点函数只专注于方法的参数-->
<aop:pointcut id="pc" expression="args(..)">

      切入点函数within():

<!--此切入点函数针对包和类作为切入点-->
<aop:pointcut id="pc" expression="within(*.UserServiceimpl.*)"/>

      切入点函数@annotation():

<!--此切入点针对注解进行切入-->
<aop:potintcut id="pc" @annotation(dynamicproxy.Log)/>

      切入点函数可以进行逻辑运算:and or not。

      e、组装 切入点+额外功能

<!--配置额外功能类-->
<bean id="before" class="xxx.xxx.MyInterceptor"/>
<!--组装切面-->
<aop:advisor pointcut-ref="pc" advice-ref="before"/>

    通过原始类的id获得代理对象,通过原始类的接口接受代理对象。 

二、AOP的实现原理:

  AOP=代理+BeanPostProcessor(后置处理Bean)

  1、原始JDK的动态代理技术(基于接口)

    a、类加载器

    b、原始对象所实现的接口

    c、额外功能InvacationHandler

pubic class TestJDKProxy{

    @Test
    public void test(){
        final UserService us = new UserServiceImpl();

        //调用JDKProxy的方法
        //1、使用Classloader
        //2、原始对象所实现的接口
        //3、额外功能InvocationHandler

        InvocationHandler hi = new InvocationHandler(){

        // method:原始方法
        // args:原始方法的参数
        // 返回值:原始方法的返回值

            public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
        //添加额外功能
            Object ret = method.invoke(us,args);

            return ret;
            }

        };

        UserService usp = (UserService)Proxy.newProxyInstance(UserServiceImpl.class.getClassLoader(),us.getClass.getInterfaces(),hi);
        //usp即为代理对象
        usp.login("zhangsan","123456");       

    }

}    

  2、cglib动态字节码增加技术完成(基于继承的方式)

public class TestCglibProxy{
    @Test
    public void test(){

        final AdminService as = new AdminServiceImpl();

        Enhancer enhancer = new Enhancer();

        //设置父类
        enhancer.setSuperclass(os.getClass);
        //创建额外功能
        InvocationHander hi = new InvocationHander(){
            public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{
            //添加额外功能
            Object ret = method.invoke(as,args);
            }
        };

        //设置额外功能
        enhancer.setCallback(hi);
        //创建代理类
        AdminService asp = (AdminService)enhancer.creat();

        asp.login(admin);
    }
}

  3、BeanPostProcessor示例图

        

浅谈Spring(二)的更多相关文章

  1. 浅谈Spring中的Quartz配置

    浅谈Spring中的Quartz配置 2009-06-26 14:04 樊凯 博客园 字号:T | T Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz,下面就看看在 ...

  2. 浅谈Spring的两种配置容器

    浅谈Spring的两种配置容器 原文:https://www.jb51.net/article/126295.htm 更新时间:2017年10月20日 08:44:41   作者:黄小鱼ZZZ     ...

  3. 1.1浅谈Spring(一个叫春的框架)

    如今各种Spring框架甚嚣尘上,但是终归还是属于spring的东西.所以在这里,个人谈一谈对spring的认识,笔者觉得掌握spring原理以及spring所涉及到的设计模式对我们具有极大的帮助.我 ...

  4. 浅谈Spring MVC知识

    关于MVC框架,我相信大家都不陌生,都会说也就是模型-视图-控制器这三层的框架结构,如果你参加面试的时候考官会问:“MVC框架是什么?你说一说.”其实我们都知道这个问题还需要问的,只要你是一个开发人员 ...

  5. Android开发-浅谈架构(二)

    写在前面的话 我记得有一期罗胖的<罗辑思维>中他提到 我们在这个碎片化 充满焦虑的时代该怎么学习--用30%的时间 了解70%该领域的知识然后迅速转移芳草鲜美的地方 像游牧民族那样.原话应 ...

  6. 浅谈Spring发展史

    1 码农的春天----------Spring来了 Spring官网 :http://www.springframework.org 关于Spring的发展起源要回溯到2002年,当时正是Java E ...

  7. 浅谈spring security 403机制

    403就是access denied ,就是请求拒绝,因为权限不足 三种权限级别 一.无权限访问 <security:http security="none" pattern ...

  8. [SSH 3]以网上商城项目浅谈spring配置

    导读:在做ITOO项目的时候,就用到了容器+反射,从而运用了依赖注入和依赖查找.如果看过WCF端的配置文件,那么对于这个spring的配置就很容易理解.本篇博客,是对于自己做的一个小项目中所运用到的s ...

  9. 浅谈Spring(三)

    一.基础Spring的标准测试 1.导入spring与junit继承的jar 2.引入注解 @RunWith(SpringJUnit4ClassRunner.class) @ContextConfig ...

随机推荐

  1. C语言中一些非常酷的技巧(cool tricks)

    来自Quora,认为不错,就实践了一下. 1.  #if 0 ...... #endif 块中的内容不会被编译,由于凝视不同意嵌套,我们能够把临时不用的代码块放在 这里面. 2. 数组初始化的时候能够 ...

  2. iSCSI存储系统知识

    一.概述 SCSI 即小型计算机系统接口(Small Computer System Interface:简写:SCSI),一种用于计算机和外部设备之间(硬盘.光驱.软驱.打印机等)系统级接口的独立处 ...

  3. AutoResetEvent和ManualResetEvent

    本文在于巩固基础 AutoResetEvent 概念:通知正在等待的线程已发生的事件 如果AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资 ...

  4. 查看EBS R12应用中使用CONTEXT_FILE的版本及路径

    SELECT * FROM APPLSYS.FND_OAM_CONTEXT_FILES;

  5. c#接口和new关键字和属性访问器基础收获

    1.interface 对于接口,一把我在项目中会这样使用: interface IStudent { string Name(); string GoSchool(); } 但是呢,这样有个不好的地 ...

  6. Android setOnTouchListener识别滑动手势

    setOnTouchListener(new OnTouchListener() { private float startX, startY, offsetX, offsetY; @Override ...

  7. php数组排序和分割字符串

    function sortStr($str){ $ary = str_split($str); sort($ary); $len = count($ary); $arr = array(); for( ...

  8. Android IT资讯网络阅读器应用源码

    这个是Android IT资讯网络阅读器应用,也是一款通过jsoup解析Html获取内容的网络阅读器,和前面的其实是类似的,也是大学时期闲暇完成,对照CSDN的Web页面元素设计进行解析提取内容,核心 ...

  9. 求一个int型整数的两种递减数之和(华为2015笔试题及答案)

    给出一个整数(负数使用其绝对值),输出这个整数中的两种递减数(1.最大递减数:2.递减数中各位数之和最大的数)之和. 递减数:一个数字的递减数是指相邻的数位从大到小排列的数字,不包含相邻的数位大小相同 ...

  10. RobotFramework环境搭建

    环境搭建 1. 准备条件 python-2.7.7 https://www.python.org/download/releases/2.7.7/ wxPython2.8-win32-unicode- ...