zoukankan      html  css  js  c++  java
  • Spring-AOP

    面向切面编程(AOP)

    1.横切关注点

    在软件开发中,把散布在应用各处的功能称为横切关注点,比如日志、安全。
    通常横切关注点是与我们的业务逻辑相互嵌套的,而AOP就是为了将横切关注点和业务逻辑分离。

    2.切面

    横切关注点可以模块化为特殊的类,这些类称为切面,它是通知和切点的结合。如下图所示:

    切面取代了继承和委托,使用AOP,我们仍然在一个地方定义通用功能,但是可以通过声明的方式定义这个功能以何种方式在何处应用,而不修改受影响的类。

    3.通知

    在AOP术语中,切面的工作被称为通知,它定义了切面是什么以及何时使用。Spring切面定义了五种通知:

    • Before:在目标方法调用前执行通知
    • After:在目标方法调用后执行通知
    • After-returning:在目标方法成功执行后执行通知
    • After-throwing:在目标方法抛出异常时执行通知
    • Around:在目标方法调用前和调用后执行通知

    4.连接点

    连接点是应用执行过程中能够插入切面的一个点,其可能是调用方法时、抛出异常时、甚至修改一个字段时。

    5.切点

    切点定义了切面所通知的连接点的范围,即在何处应用切面。

    6.织入

    织入是把切面应用到目标对象并创建新的代理对象的过程。

    7.动态代理

    Spring AOP是在运行期将切面织入到Spring管理的bean中的,即Spring是基于动态代理的。
    代理类包裹了切面,封装了目标类,并会拦截对目标类的方法调用。当代理拦截到方法调用时,先执行切面逻辑,之后把调用转发给真正的目标bean。
    注意:基于JDK的动态代理只能代理实现了接口的类,基于cglib的采用继承的方式,两种类都可以代理。因为final类和静态方法是不能被代理的,所以aop也不能织入静态方法。

    配置AOP

    Spring框架集合了ProxyFactory和Cglib两种方式来实现AOP。Spring AOP能够根据上下文环境选择其一,一般而言,当业务对象实现了接口时会选择基于JDK的动态代理;当业务对象没有实现接口时会选择Cglib动态对目标对象进行子类化;如果实现了接口却发生异常,需开启@EnableAspectJAutoProxy(proxyTargetClass = true)强制使用Cglib。

    1.在xml中配置

    Spring的AOP配置元素能够以非侵入性的方式声明切面。
    大多数的AOP配置元素必须 在<aop:config>元素的上下文内使用。使用<aop:aspect>元素中的ref属性可以声明一个简单的切面。部分配置元素如下:

    • <aop:after>
    • <aop:before>
    • <aop:around>
    • <aop:after-returning>
    • <aop:after-throwing>
    • <aop:aspect>定义一个切面
    • <aop:pointcut>定义一个切点

    2.使用注解配置

    • 首先创建一个切面类,使用@Aspect注解此类声明为切面
    • 创建无参无方法体的方法作为切点ID,并使用@Pointcut("execution(* com.crab.service..(..))")注解的形式声明一个切点
    • 创建增强的方法体,添加如@Before("anyCut()")的注解,anyCut为上一步创建的切点

    Spring AOP实战测试

    在IOC的基础上需要的包如下:

    1.使用xml配置

    使用示例如下:

       <!-- 启用注解配置 -->
    <!--    <aop:aspectj-autoproxy /> -->
    
        <!-- proxy-target-class属性默认为false,表示使用DynamicProxy实现AOP,设置为true表示使用Cglib实现AOP -->
       <aop:config proxy-target-class="true">
       
         <!-- 定义全局切点,后面使用id引入 -->
         <aop:pointcut id="anyCut" expression="execution(* com.crab.service.Tom.*(..))"/>
         
         <!-- 定义切面,ref指代理类的bean -->
         <aop:aspect ref="aspectDemo">
         
             <!-- 将切面织入切点,使用切面的method方法增强切点方法,在切点方法之前执行 -->
             <aop:before pointcut-ref="anyCut" method="divBefore" />
             
             <!-- 直接配置局部切点 -->
             <aop:after pointcut="execution(* com.crab.service.Tom.say(..))" method="divAfter" />
         </aop:aspect>
       </aop:config>
    

    其中限制切点范围的execution中的内容分别表示:execution(类的返回类型+空格+类的方法的全限定名+(方法参数)),以*开始,表明了我们不关心方法返回值的类型。然后,我们指定了全限定类名和方法名。对于方法参数列表,我们使用两个点号(..)表明切点要选择任意的相应方法,无论该方法参数是什么。

    2.使用注解配置

    使用示例如下:

    //声明此类为切面
    @Aspect
    //告知Spring为此类创建bean
    @Component
    public class AnnoAspect {
    
    	//声明一个切入点,这里是service包里的所有方法,无参无方法体的方法名为切入点ID
    	@Pointcut("execution(* com.crab.service.*.*(..))")
    	private void anyCut() {} 
    	
    	@Pointcut("execution(* com.crab.service.Tom.say(..))")
    	private void roundCut() {}
    	
    	@Before("anyCut()")
    	public void divBef() {
    		System.out.println("----------before-----------");
    	}
    	
    	@Around("roundCut()")
    	public void divAft() {
    		System.out.println("----------round-----------");
    	}
    }
    

    参考书籍

    《Spring In Action》

  • 相关阅读:
    webim-界面细节调整
    使用PHP得到所有的HTTP请求头_还有应答头
    Bootstrap学习的点点滴滴
    asterisk中eyebeam与移动的IMS帐号对接
    总结Ajax跨域调用问题
    Spring【基础】-注解-转载
    Spring-【高阶】注解-转载
    让你的IDEA倍爽
    IDEA的git密码修改
    Idea设置签名
  • 原文地址:https://www.cnblogs.com/pycrab/p/9774848.html
Copyright © 2011-2022 走看看