zoukankan      html  css  js  c++  java
  • 《Spring揭秘》--AOP笔记

    静态AOP与动态AOP

    静态AOP  将各个Aspect以Java字节码的形式编译到系统的各个功能模块中,以达到融合Aspect和Class的目的.  没有性能损失,但不够灵活.

    动态AOP  AOP的各种概念实体都是普通的Java类,AOP的织入过程在系统运行开始之后进行.  因此,可以在调整植入点以及织入逻辑单元的同时,不必变更系统其他模块,甚至在系统运行时,可以动态更改织入逻辑.  采用对系统字节码操作方式来完成织入,性能损失.

    一些概念

    Joinpoint  程序执行过程中你认为必要的执行时点

    Pointcut  指定了系统中符合条件的一组JoinPoint

    Advice  单一横切关注点逻辑的载体,代表将会织入到Joinpoint的横切逻辑,相当于Class的Method. 

         Before Advice, After Advice(After returning Advice, After throwing Advice, After Advice), Around Advice(即将Jointpoint包围起来), Introduction(为原有的对象添加新的特性或者行为,AspectJ中使用静态织入,Spring AOP中使用动态织入)

    Aspect  Pointcut和Advice的集合

    Weaver  Spring AOP使用ProxyFactory类作为最通用的织入器;AspectJ使用专门的编译器ajc完成织入操作.

    实现机制

    静态代理

    动态代理  Spring AOP发现目标对象实现了相应Interface,则采用动态代理技术为其生成代理对象实例.而如果没有实现任何Interface,则会尝试使用CGLIB的动态字节码生成类库,为目标对象生成动态的代理对象实例.

    动态字节码生成  借助于CGLIB这样的动态字节码生成库,在系统运行期间动态地为目标对象生成相应的扩展子类. 唯一限制及无法对final对象进行覆写.

    Spring AOP的实现1

    Pointcut

    关联的实体有:

    ClassFilter

    MethodMatcher  StaticMethodMatcher  DynamicMethodMatcher(每次对方法参数进行检查,无法对匹配的结果进行缓存,所以匹配效率相对StaticMethodMatcher要差.)

    基于MethodMatcher的不同,Pointcut可以分为两类:StaticMethodMatcherPointcut, DynamicMethodMatcherPointcut

    常见的Pointcut:

    1.NameMatchMethodPointcut  仅对方法名做匹配,支持"*"通配符.

    2.

    JdkMatchMethodPointcut  基于jdk1.4之后引入的JDK标准正则表达式

    Perl5MatchMethodPointcut  支持使用Jakarta ORO提供正则表达式支持

    以上均可以指定一个或多个正则表达式的匹配模式;必须以匹配整个方法签名的形式指定,而不是像NameMatchMethodPointcut仅给出匹配的方法名称.

    3.AnnotationMatchingPointcut

    根据目标对象是否存在指定类型的注解来匹配Joinpoint.

    4.ComposablePointcut  可以进行Pointcut逻辑运算的Pointcut实现

    5.ControlFlowPointcut  

    匹配程序的调用流程,不是对某个方法执行所在的Joinpoint处的单一特征进行匹配.即限制只有在某一类对象调用其他相关类的方法时才会织入Advice.

    该Pointcut需要在运行期间检查程序的调用栈,而且每次方法调用都需要检查,所以性能比较差.

    Advice

    pre-class类型的Advice  只是提供方法拦截的功能,不会为目标对象类保存任何状态或者添加新特性.

    Before Advice

    ThrowsAdvice  普通异常处理,运行时异常处理,应用程序生成的异常处理

    AfterReturningAdvice  可以访问方法的返回值,但是不可以更改

    注意:Spring AOP不提供After(Finally) Advice

    AroundAdvice  采用AOP Alliance的标准接口,即org.aopalliance.intercept.MethodInterceptor.  系统安全验证及检查,系统各处的性能检测,简单的日志记录以及系统附加行为的添加.

    pre-instance类型的Advice  为不同的实例对象保存它们各自的状态以及相关逻辑

    相关的拦截器为:org.springframework.aop.IntroductionInterceptor

    两个实现类

    DelegatingIntroductionInterceptor

    DelegatePerTargetObjectIntroductionInterceptor

    Spring AOP中对Introduction采用动态代理机制,性能上要逊色不少.

    Aspect

    Advisor代表Spring AOP中的Aspect,但通常只持有一个Pointcut和Advice.

    PointcutAdvisor分支

    DefaultPointcutAdvisor  除了不能指定Introduction类型的Advice外,剩下任何类型的Pointcut,Advice都可以指定.

    NameMatchMethodPointcutAdvisor  限定Pointcut类型为NameMatchMethodPointcut,而且外部不可更改.Advice不能为Introduction类型.

    RegexpMethodPointcutAdvisor  限定Pointcut为AbstractRegexpMethodPointcut

    DefaultBeanFactoryPointcutAdvisor  通过容器中的Advice注册的beanName来关联对应的Advice

    InstructionAdvisor分支

    DefaultIntroductionAdvisor只可以指定Introduction型的Advice以及被拦截的接口类型.

    Order作用

    指定各个Advisor的执行顺序

    Spring AOP的织入

    ProxyFactory  基本的织入器

    ProxyFactoryBean  生成Proxy的FactoryBean

    自动代理机制

    两个实现类

    BeanNameAutoProxyCreator  

    DefaultAdvisorAutoProxyCreator

    自动代理实现的原理:  建立在IoC容器的BeanPostProcessor之上.

    TargetSource

    SingletonTargetSource

    PrototypeTargetSource

    HotSwappableTargetSource

    CommonsPoolTargetSource

    ThreadLocalTargetSource

    Spring AOP的实现2

    @Aspect形式的Spring AOP

    使用

    编程方法织入  AspectJProxyFactory

    自动代理织入  AnnotationAwareAspectJAutoProxyCreator  即注册<aop:aspect-autoproxy proxy-target-class="true">

    @Aspect形式的Pointcut

    @AspectJ形式的Pointcut包含了两个部分:

    Pointcut Expression

    支持&&  ||  !逻辑运算符  

    支持的表示符:

      execution 支持* , . 以及..

      within  只接受类型声明,匹配指定类型下所有的Joinpoint.

      this和target  this指定调用方法一方所在的对象,target指定被调用方法所在的对象.

      args  捕捉拥有指定参数类型,指定参数数量的方法及Joinpoint,而不管该方法在什么类型中声明.

      @within  指定某种类型的注解,只要对象标注了该类型的注解,那么将匹配该对象内部所有Joinpoint.

      @target  与@within类似.只不过@within属于静态匹配,而@target则是在运行时点动态匹配Joinpoint.

      @args  检查当前方法及的Joinpoint的方法参数类型,若该次传入的参数类型拥有@args所指定的注解,当前Joinpoint即被匹配.

      @annotation  检查系统中所有对象的所有方法级别Joinpoint,如果被检测的方法标注有@annotation标志符所指定的注解类型,那么匹配当前方法所在的Joinpoint.

    Pointcut Signature

    @Aspect形式的Advice

    @Before  value必须指定,可以直接指定Pointcut表达式,也可以指定Pointcut定义的Pointcut Signature

    @AfterReturning  

    @AfterThrowing

    @After

    @Around

    @DeclareParents  标注Introduction类型的Advice,标注的是域

    Advice的执行顺序

    声明在同一个Aspect中的Advice的执行顺序,由它们在Aspect中的声明顺序决定.

    不是生命在同一个Aspect中的Advice,需要实现org.springframework.core.Ordered接口.

    Aspect的实例化模式

    对于注册到容器的各个Aspect,它们的默认的实例化模式采用的是singleton.

    Spring2.0之后的AOP只支持默认的singleton,perthis,pertarget.

    注意:使用perthis或者pertarget指定了Aspect的实例化模式之后,将这些Aspect注册到容器中,不能为其bean定义指定为singleton的scope.

    基于Schema的AOP

    1.x版本的Spring AOP向Schema的迁移

    <aop:config proxy-target-class=true/false>  proxy-target-class控制是基于接口的代理还是基于类的代理

    <aop:config>取代各种AutoProxyCreator,底层基本上使用1.x中的自动代理机制实现的.

    <aop:advisor>代替各种具体的Advisor实现类的bena定义声明

    <aop:advisor>有id,pointcut-ref,advice-ref,order属性,另外还有pointcut属性(只能指定AspectJ形式的Pointcut表达式)

    @AspectJ到Schema的AOP的迁移

    <aop:aspect>有三个属性:id,ref,order

    <aop:pointcut>有两个属性id,expression(支持逻辑运算符and,or,not代替&&,||,!)

    <aop:before>属性pointcut-ref,method

    <aop:after-returning>

    <aop:after-throwing>

    <aop:after>

    <aop:around>

    <aop:declare-parents>属性types-matching,implement-interface,default-impl

    Aspect的实例化模式

    虽然@Aspect形式的AOP支持singleton,perthis,pertarget,然而基于Schema的AOP只支持singleton实例化模式.

  • 相关阅读:
    BZOJ3501 : PA2008 Cliquers Strike Back
    BZOJ3500 : PA2008 Cliquers
    BZOJ2280 : [Poi2011]Plot
    BZOJ2924 : [Poi1998]Flat broken lines
    BZOJ2911 : [Poi1997]The Number of Symmetrical Choices
    BZOJ2612 : [Poi2003]Sums
    BZOJ4025 : 二分图
    BZOJ2213 : [Poi2011]Difference
    BZOJ2215 : [Poi2011]Conspiracy
    BZOJ2278 : [Poi2011]Garbage
  • 原文地址:https://www.cnblogs.com/cheungchein/p/8952677.html
Copyright © 2011-2022 走看看