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的全局扫描

原文地址:https://www.cnblogs.com/1439107348s/p/14291738.html