Spring学习笔记三:面向切面的Spring

    首先了解什么是面向切面编程,这里不做描述。
1.Spring对AOP的支持
        Spring提供了4种类型的AOP支持
      ① 基于代理的经典Spring AOP
      ② 纯POJO切面
      ③ @AspectJ 注解驱动的切面
       ④ 注入式AspectJ 切面
Spring AOP构建在动态代理之上,所以Spring对AOP的支持局限于方法拦截。
 Spring在运行时通知对象:通过在代理类中包裹切面,Spring在运行期把切面织入到Spring管理的bean中。代理类封装了目标类,并拦截被通知方法的调用,当拦截到目标方法被调用时,代理类会在目标方法执行前执行切面逻辑。
2.通过切点来选择连接点
    切点用于定位在什么位置应用切面的通知。Spring借助ASpectJ 的切点表达式语言来定义Spring切面。
    AspectJ指示器                                               描述       
    arg()                                             限制连接点匹配参数为指定类型的执行方法
    @args()                                        限制连接点匹配参数由指定注解标注的执行方法
    execution()                                   用于匹配是连接点的执行方法
    this()                                             限制连接点匹配的AOP代理的bean引用为指定类型的类
    target()                                         限定连接点匹配目标对象为指定类型的类对象
    within ()                                        限制连接点匹配指定的类型
    @within()                                     限制连接点匹配指定注解所标注的类型
    @annotation                               限定匹配带有指定注解的连接点
2.1编写切入点
    定义一个Performance接口
    package concert;
    
  public interface Performance{
            
             public void perform();

            }
编写perform()方法执行时触发的通知的切点表达式,execution(* concert.Performance.perform(..) ).这个表达式能够设置当perform()方法执行时触发通知的调用。这里使用了execution()指示器选择Performance的perform()方法。方法表达式以*开始,表明不关心方法的返回值的类型,然后指定方法的全限定类名和方法名,参数列表使用了  . . 表示切点要选择任意的perform()方法,无论方法的入参是什么。
        假设现在需要配置切点仅匹配concert包,可以使用within()指示器来限制匹配,
        execution(* concert.Performance.perform(..)  && within(concert.*))
XML中使用and替代&&
3.创建切面
    可以使用@AspectJ注解定义切面类。
比如需要在上面的Performance接口的perform()方法执行一些通知。比如前置通知后置通知等,可以定义如下的切面。
package concert;

@AspectJ
public class Audience{
    
        //前置通知
    @Before("execution(*  concert.Performance.perform(..))")
    public void before(){
            System.out.println("表演开始前");
        }

    //后置通知
    @After("execution(* concert.Performance.perform(..))")
    public void after(){
            System.out.println("表演已经结束");
        }
    
    //异常通知
    @AfterThrowing("execution(* concert.Performance.perform(..))")
    public void afterThrow(){
            System.out.println("方法执行发生异常后执行");

        }

}
上面定义了一个切面,但是Spring并不会把它作为切面,还需要做下面的配置。下面使用JavaConfig进行配置。
     
    package concert;
    /**
    * Java配置类,启动扫描,启动AspectJ自动代理
    *
    */
    @Configuration
    @EnableAspectJ  //启动AspectJ自动代理
    @ComponetScan
    public class ConcertConfig{
            @Bean
            public Audience audience(){
                    return new Audience();
            }

        }
这样,每次在perform()方法前后及发生异常都会执行切面里面定义的通知方法。
        这里需要注意一下环绕通知的定义。如下定义了方法的环绕通知。(注意其中的 ProceedingJoinPoint类型参数)
    @Around("execution(* concert.Performance.perform(..))")
    public void around(ProceedingJoinPoint pj){
                System.out.print("环绕通知。。。。");
               try{ 
                pj.proceed();
                }catch(Exception e){
                }
                System.out.println("环绕通知。。。。");

        }
如果  pj.proceed()不调用此方法则目标方法perform不会被执行。
4.使用XML配置切面及通知
        Spring AOP的配置元素必须在元素的上下文中使用。
    首先声明一个类:
           
然后在元素中将上述声明的类引用为切面,并且定义切点等。
       
             
           
     
    
































你可能感兴趣的:(Spring,aop,学习笔记)