zoukankan      html  css  js  c++  java
  • spring 基础(三) spring Aop

     AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

    1.基础

    1. 在不修改源码的情况下对程序行为进行扩展。
    2. Spring AOP - Aspect Oriented Programming面向切面编程
    3. AOP的做法是将通用、与业务无关的功能抽象封装为切面类
    4. 切面可配置在目标方法的执行前、后运行,真正做到即插即用
    5. SpringAopAspectJ的关系:
      1. Eclipse AspectJ,一种基于Java平台的面向切面编程的语言。
      2. Spring AOP使用AspectJWeaver实现类与方法匹配。
      3. Spring AOP利用代理模式实现对象运行时功能扩展。
    6. SpringAop的导包
      1.   
    7. 使用aopxml配置=spring.io=>springframework=the apo schema


    8. 一个简单的demo(关键字:切面类(JoinPoint:连接点、通过连接点可以获取目标点/方法的信息)):

      1.  <!-- AOP配置 -->
            <bean id="methodAspect" class="com.imooc.spring.aop.aspect.MethodAspect"></bean>
            <aop:config>
                <!-- PointCut 切点,使用execution表达式描述切面的作用范围 -->
                <!-- execution(public * com.imooc..*.*(..)) 说明切面作用在com.imooc包下的所有类的所有方法上 -->
                <aop:pointcut id="pointcut" expression="execution(public * com.imooc..*.*(..))"></aop:pointcut>
                <!--只对所有Service类生效-->
        <!--        <aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.*(..))"></aop:pointcut>-->
                <!--只对所有返回值为String类型方法生效-->
                <!--<aop:pointcut id="pointcut" expression="execution(String com.imooc..*Service.*(..))"></aop:pointcut>-->
                <!--对方法名进行约束 -->
                <!--<aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.create*(..))"></aop:pointcut>-->
                <!-- 对参数进行约束 -->
                <!--<aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.*(String,*))"></aop:pointcut>-->
                <!-- 定义切面类 -->
                <aop:aspect ref="methodAspect">
                    <!-- before通知(Advice),代表在目标方法运行前先执行methodAspect.printExecutionTime() -->
                    <aop:before method="printExecutionTime" pointcut-ref="pointcut"/>
                </aop:aspect>
            </aop:config>

     

    2.有关参数

    2.1基础

    1. Object  getTarget():获取IoC容器内目标对象。
    2. Signature  getSignature()获取目标方法。
    3. Object[]  getArgs() 获取目标方法参数。
    4. demo(从基础的demo中拓展过来)
      1.   

    2.2PointCut切点表达式

    * 通配符:一切可出现情况

    ..:对包的省略

    (..):对参数的省略,对填写的参数数量、类型都不做限制

     <aop:config>
            <!-- PointCut 切点,使用execution表达式描述切面的作用范围 -->
            <!-- execution(public * com.imooc..*.*(..)) 说明切面作用在com.imooc包下的所有类的所有方法上 -->
            <aop:pointcut id="pointcut" expression="execution(public * com.imooc..*.*(..))"></aop:pointcut>
            <!--只对所有Service类生效  只要类名是 Service结尾的就行 比如 appService-->
    <!--        <aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.*(..))"></aop:pointcut>-->
            <!--只对所有返回值为String类型方法生效-->
            <!--<aop:pointcut id="pointcut" expression="execution(String com.imooc..*Service.*(..))"></aop:pointcut>-->
            <!--对方法名进行约束  对create开头的方法进行捕获 -->
            <!--<aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.create*(..))"></aop:pointcut>-->
            <!-- 对参数进行约束 比如目前只要两个参数,且第一个为string类型-->
            <!--<aop:pointcut id="pointcut" expression="execution(* com.imooc..*Service.*(String,*))"></aop:pointcut>-->
            <!-- 定义切面类 -->
            <aop:aspect ref="methodAspect">
                <!-- before通知(Advice),代表在目标方法运行前先执行methodAspect.printExecutionTime() -->
                <aop:before method="printExecutionTime" pointcut-ref="pointcut"/>
            </aop:aspect>
        </aop:config>

    3.五种环绕通知

    1. Before Advice:执行前通知,目标方法运行前执行。
    2. After Returning Advice :返回后通知,目标方法返回数据后执行。【执行成功之后返回】
    3. After Throwing Advice: 异常通知,目标方法抛出异常后执行。【执行异常之后返回】
    4. After Advice :最后(最终)通知,目标方法运行后执行。【无法获取返回值或者内部抛出异常】
    5. Around Advice (环绕通知):最强大通知,自定义通知执行时机,可决定目标方法是否运行。
    6.   After Returning Advice和After Throwing Advice二者只能额选其一。
    7.   After Returning Advice和After Advice和After Throwing Advice的执行顺序由配置的顺序决定。
    8.   特殊的通知:引介增强
      1. 引介增强(IntroductionInterceptor)是对类的增强,而非方法。
      2. 引介增强允许在运行时为目标类增加新属性或方法。
      3. 引介增强允许在运行时改变类的行为,让类随运行环境动态变更
    9. 除了环绕通知的demo:
    10. 环绕通知demo,关键字 Object(返回值必须是这个) ProceedingJoinPoint:

    4.aop注解模式

    1. 五种通知方法:
      1. 前置通知(@Before)
      2. 后置通知(@After)
      3. 返回通知 (@AfterReturning)
      4. 异常通知 (@AfterThrowing)
      5. 环绕通知 (@Around)
    2. @PointCut:公共切入点表达式
    3. JoinPoint: 作为函数的参数传入切面方法,可以得到目标方法的相关信息
    4. @Aspect : 指定切面类
    5. @EnableAspectJAutoProxy : 开启基于注解的AOP模式
    6. demo(依旧是xml中配置)
    7. demo2.程序中配置

    5.springAop底层实现原理(代理)

    5.1基础

    1. 代理=》加强原始方法或者类。可以随时添加删除且不影响原始代码(类似浏览器插件,可要可不要。对浏览器本身没有影响)。
    2. Spring基于代理模式实现功能动态扩展,包含两种形式:
      1.   目标类拥有接口,通过JDK动态代理实现功能扩展。
      2.   目标类没有接口,通过CGLib组件实现功能扩展。

    5.2静态代理

    1. 代理类和委托类实现相同的接口。 代理类对功能有额外的拓展。
    2. 静态代理使用:
      1.   
    3. 代理类嵌套使用
      1.  

    5.3jdk动态代理

    1. jdk代理基于反射完成。
    2. demo:
      1.   

    5.3CGLib实现代理类

    1. CGLib是运行时字节码增强技术。
    2. Spring AOP扩展无接口类使用CGLib。
    3. AOP会运行时生成目标继承类字节码的方式进行行为扩展。
    4. 如果目标类实现了接口:就是用jdk动态代理
      1.   
    5. 如果目标类没有实现接口则使用CGLib代理
      1.   

    待完善=》aop注解方式,实现xml的全局扫描

  • 相关阅读:
    剑指21.栈的压入、弹出序列
    剑指20.包含min函数的栈
    剑指19.顺时针打印矩阵
    Java--使用反编译工具,打开jar包,查看源码
    没想到 Unicode 字符还能这样玩?
    angularjs中响应回车事件
    两个很好的angular调试工具-——batarang(stable)和ng-inspector
    基于 ThinkPHP5 的 cltphp 被搜索劫持,篡改首页的解决过程记录
    国内外CDN服务商CNAME特征串调研
    开源中国/码云 README.md上传图片的爬坑记录
  • 原文地址:https://www.cnblogs.com/1439107348s/p/14291738.html
Copyright © 2011-2022 走看看