Spring AOP知识点整理

2、AOP
     2.1 AOP中的概念 ?
        1)、Joinpoint
            要在其上进行织入操作的系统执行点就称之为Joinpoint。常见的Joinpoint类型为:方法调用(Method Call)、方法调用执行(Method Call execution)、构造方法调用(Constructor Call)、字段设置(Field Set)、字段获取(Field Get)、异常处理执行(Exception Handler Execution)、类初始化(Class initialization)。
        2)、Pointcut
            它代表的是Joinpoint的表述方法。将横切逻辑织入当前系统的过程中,需要参照Pointcut规定的JoinPoint信息,才可以知道应该往系统的哪些Joinpoint上织入横切逻辑。
        3)、Advice
        它是单一横切关注点逻辑的载体,它代表将会织入到Joinpoint的横切逻辑。按照Advice在Joinpoint位置执行时机的差异或者完成功能的不同,Advice可以分成:
            ①、Before Advice
                Before Advice 是在Joinpoint指定位置之前执行的Advice类型。
            ②、After Advice
                它再Joinpoint之后执行的Advice类型。可细分为After returning Advice、After throwing Advice和After Advice。
            ③、Around Advice
                它对附加在其上的Joinpoint进行“包裹”,可以在Joinpoint的之前或之后都指定相应的横切逻辑,甚至于可以中断或者忽略Joinpoint处的原来程序流程的执行。
            ④、Introduction
                与之前的几种Advice类型不同,Introduction不是根据横切逻辑在Joinpoint处执行时机来区分的,而是根据它可以完成的功能而区别其它Advice类型。Introduction可以为原有的对象添加新的特性或者行为。
        4)、Aspect
            它是对系统中的横切关注点逻辑进行模块化封装的AOP概念实体。通常情况下,Aspect可以包含多个Pointcut以及相关Advice定义。
        5)、织入和织入器
            把AOP中的Aspect模块化的横切逻辑通过织入器织入到OOP的系统中。
        6)、目标对象
            符合Point所指定的条件,将在织入过程中被织入横切逻辑的对象,称为目标对象(Target Object)。
    2.2、Java平台上的AOP实现机制有哪些 ?
        动态代理(如Spring AOP默认使用的就是动态代理)、动态字节码生成(如ASM和CGLIB)、自定义类加载器(如JBoss AOP)、AOL扩展(如AspectJ)。
    2.3、Spring中AOP使用哪些机制实现的 ?
        动态代理和动态字节码生成(CGLIB)。默认情况下,如果Spring AOP发现目标对象实现了相应的Interface,则采用动态代理机制为其生成代理对象实例。而如果目标对象没有实现任何Interface,Spring AOP 会尝试使用CGLIB为目标对象生成代理对象。
    2.4、Spring AOP 中的Joinpoint ?
        在Spring AOP中,仅支持方法基本的Joinpoint(具体的说,只支持方法执行(Method Execution)类型的JoinPoint)。
    2.5、Spring AOP中常见的Pointcut有哪些?
        可分为:(抽象类)AbstractExpressPointcut、staticMethodMatcherPointcut、DynamicMethodMathcerPointcut、AnnotationMatchingPointcut、ComposablePointcut和ControlFlowPointcut。
        常见的Pointcut有:
        ①、AspectJExpressPointcut(继承自AbstractExpressPointcut),主要用于@AspectJ形式声明的所有Joinpoint表达式来指定Joinpoint。
        ②、JdkRegexpMethodPointcut(属于staticMethodMatcherPointcut的子类),用正则表达式匹配方法的签名(Joinpoint)。
        ③、NameMatchMethodPointcut(属于staticMethodMatcherPointcut的子类),用指定的方法名去匹配Joinpoint。
        ④、AnnotationMatchingPointcut,根据目标对象中是否存在指定的类型的注解来匹配Joinpoint。
        ⑤、ComposablePointcut,提供了Pointcut之间的逻辑运算。
        ⑥、ControlFlowPointcut,匹配程序的调用流程,不是对某个方法执行所在的Joinpoint处的单一特征进行匹配。
        ⑦、也可以自定义Pointcut类型。
    2.6、Spring 中AOP中常见的Advice有哪些?
        1)、per-class类型的Advice(该类型的Advice的实例可以在目标对象类的实例之间共享)
            ①、Before Advice ②、ThrowsAdvice ③、AfterReturningAdvice ④、Around Advice(MethodIterceptor,Spring直接使用AOP Alliance的这个标准接口)
        2)、per-instance类型的Advice(该类型的Advice为不同的实例对象保存它们各自的状态以及相关逻辑)
            Introduction(Introduction可以在不改动目标对象定义的情况下,为目标对象添加新的属性以及行为),有两个分支IntroductionInfo(常用其子类DelegationIntroductionInterceptor)和DynamicIntroductionAdvice(常用其子类DelegatePerTargetObjectInterceptor)。
    2.7、Spring AOP 中的Aspect ?
        Spring 中最初没有完全明确的Aspect 的概念,但是并不意味着没有。只不过,Spring 中的这个Aspect在实现和特性上有特殊而已。Advisor代表Spring中的Aspect,但是,与正常的Aspect不同的是,Advisor通常只持有一个Pointcut和一个Advice。
        Advisor可分为两个分支:PointcutAdvisor和IntroductionAdvisor(只能用于类级别的拦截)。
        (1)、常用的PointcutAdvisor
        ①、DefaultPointcutAdvisor(是最通用的PointcutAdvisor实现。除了不能为其指定Introduction类型的Advice之外,剩下的任何类型的Pointcut、任何类型的Advice都可以)。
        ②、NameMatchMethodPointcutAdvisor(它限定了自身可以使用Pointcut类型为NameMatchMethodPointcut,对于除Introduction以外的其它Advice都可以使用)。
        ③、RegexpMethodPointcutAdvisor(它限定自身可以使用的Pointcut类型为JdkRggexpMethodPointcut,对于除Introduction以外的其它Advice都可以使用)。
        (2)、常用的IntroductionAdvisor
        ①、DefaultIntroductionAdvisor(仅限于为Introduction类型Advice的使用场景)。
    2.8、Spring AOP 的织入 ?
        Spring AOP 中常用的织入器有ProxyFactory(Spring AOP中最基本的织入器实现,可独立于IoC容器外使用)、ProxyFactoryBean(可以使用IoC提供的功能的织入器)、AspectJProxyFactroy(通过其可以实现Aspect定义到目标对象的织入)。
    2.9、@AspectJ形式的Spring AOP ?
        2.9.1、@AspectJ形式的Pointcut
            @AspectJ形式的Pointcut声明=Pointcut Expression + Pointcut Signature。
            1)、其中Pointcut Expression的载体为@Pointcut,该注解是方法级别的注解,所以Pointcut Expression不能脱离某个方法单独声明。Pointcut Expression附着于上的方法称为该Pointcut Expression的Pointcut Signature。
            Pointcut Expression=Pointcut标志符(Pointcut Designator)(该标志符表明Pointcut将以什么样的行为来匹配表达式) + 表达式匹配模式(在Pointcut标志符之内可以指定具体的匹配模式)。
            2)、Poincut Signature在这里具体化为一个方法定义。Pointcut Signature所在的方法定义,除了返回类型必须是void之外,没有其它限制。
            3)、@AspectJ形式Pointcut表达式的标识符
                虽然AspectJ的Pointcut表达式可用的标识符很丰富,基本上可以概括所有Joinpoint类型的表述,但是因为Spring AOP只支持方法级别的Joinpoint,所以Spring AOP只能使用AspectJ中少数几种标志符。
                ①、execution:匹配拥有方法签名的Joinpoint。
                    形如:execution(void cn.test.*.doSomething(*,String,..))
                    "*"通配符可拥有任何部分的匹配模式,匹配任何一个单词。“..”通配符可以指定多个层次的类型声明(可以用在declaring-type-pattern和方法参数中)
                ②、within:只接受类型声明,它将匹配指定类型(即类)下的所有Joinpoint。
                    形如:within(cn.test.HelloTest)
                ③、this和target:this指代的是目标对象的代理对象,而target指代的是目标对象。
                    形如:
                    this(ObjectType):使用this(ObjectType)作为Pointcut的定义,表示当目标对象的代理对象是ObjectType类型的时候,该Pointcut定义将匹配ObjectType类型中的所有Joinpoint(方法级别的,Method Execution)。
                    target(ObjectType):使用target(ObjectType)作为Pointcut的定义,表示当目标对象是ObjectType类型的时候,该Pointcut定义将匹配目标对象(ObjectType型的)内定义的定义的所有Joinpoint(Method Execution)。
                ④、args:捕获指定参数类型、指定参数数量的方法级Joinpoint,而不管该方法在什么类型中声明。args标志符会在运行期间动态检查参数的类型。
                    形如:args(cn.test.User)
                ⑤、@within:如果使用@within指定了某种类型的注解,那么只要对象标注了该类型的注解,使用了@within标志符的Pointcut表达式将匹配该对象内部声明的所有Joinpoint(方法级别的,Method Execution)。
                    形如:@within(AnyJoinpointAnnotation)
                ⑥、@Target:如果目标对象拥有@target标志符所指定的注解类型,那么目标对象对对象内部所有Joinpoint(方法级别的,Method Execution)将匹配。
                    形如:@target(AnyJoinpointAnnotation)
                ⑦、@args:使用@args标志符的Pointcut表达式将会尝试检查当前方法级别的Joinpoint的方法参数类型。如果该次传入的参数类型拥有@args所指定的注解,会将当前Joinpoint匹配,否则不会匹配。
                    形如:@args(com.test.AnyJoinpointAnnotation)
                ⑧、@annotation:使用@annotation标志符的Pointcut表达式,将会尝试检查系统中所有对象的所有方法级别Joinpoint。如果被检测的方法标志有@anntation标志符所指定的注解类型,那么当前方法所在的Joinpoint将被Poincut表达式所匹配。
                    形如:@annotation(org.springframework.transaction.annotation.Transaction)。
        2.9.2、@AspectJ形式的Advice ?
            @AspectJ形式的Advice定义,实际上就是使用@Aspect标注的Aspect定义类中的普通方法。只不过,这些方法需要针对不同的Advice类型使用对应的注解进行标注。
            除了@DeclareParents比较不同(标注在实例变量中)之外,其它用于标注不同类型Advice的注解,只能用于标注方法定义。对于Advice最终织入到什么位置,是由相应的Pointcut定义决定的。所以,我们需要为这些标注Advice的注解指定对应的Pointcut定义,也可以指定@Pointcut类型定义的Pointcut Signature。
            1)、标注对应Advice定义方法的注解
                ①、@Before:value属性用于指定@Before对应的Pointcut,可以将第一个参数声明为Joinpoint,借助它我们可以访问相应Joinpoint处的参数值。
                ②、@AfterThrowing:value属性用于指定@AfterThrowing对应的Pointcut,throwing属性用于可以限定Advice定义方法的参数名,并在方法调用的时候,将相应的异常绑定到具体方法参数上,这样就可以访问具体的异常信息。同时可以将第一个参数声明为Joinpoint,借助它我们可以访问相应Joinpoint处的参数值。
                ③、@AfterReturning:value属性用于指定@AfterReturning对应的Pointcut,returning属性将目标对象方法的返回值绑定到该AfterReturning所定义的方法参数上。同时可以将第一个参数声明为Joinpoint,借助它我们可以访问相应Joinpoint处的参数值。
                ④、@After:value属性用于指定@After对应的Pointcut,同时可以将第一个参数声明为Joinpoint,借助它我们可以访问相应Joinpoint处的参数值。
                ⑤、@Around:value属性用于指定@Around对应的Pointcut,该Around Advice的方法定义,它的第一个参数必须是ProceedingJoinPoint类型,而且必须指定。通常需要调用ProceedingJoinPoint的proceed()方法继续调用链的执行。
                ⑥、@DeclareParents:@DeclareParents注解标注在为目标对象新增加的对象类型(一般是接口)上。value属性指定将要应用到的目标对象。defaultImpl属性可以指定新增加接口的实现类。
        2.9.3、@AspectJ形式的Aspect ?
            @AspectJ形式的Aspect就是POJO+@Aspect。Aspect中的执行顺序是在同一个Aspect中声明的Advice由其声明顺序决定执行顺序。不在同一个Aspect中的通过POJO实现Ordered接口来指定顺序。
    2.10、基于Schema的AOP ?
        2.10.1、基于Schema的Aspect声明 ?
            ①、定义POJO的Aspect。
            ②、将POJO配置到容器中。
            ③、在xml中声明需要<aop:aspect>来引用它。

                形如:

                 <aop:config>
                    <aop:aspect id="myAspect" ref="aspect" order="2">
                    </aop:aspect>
                </aop:config>

                 其中:通过ref指向Aspect定义中对应的容器中的bean定义。
        2.10.2、基于Schema的Pointcut声明 ?
            形如:
                <aop:config>
                    <aop:aspect id="myAspect" ref="aspect" order="2">
                        <aop:pointcut id="myPointcut" expression="execution(public void *.doSth())"></aop:pointcut>
                    </aop:aspect>
                </aop:config>
        2.10.3、基于Schema的Advice声明 ?
            
            (以before Advice 为例)形如:
                <aop:config>
                    <aop:aspect id="myAspect" ref="aspect" order="2">
                        <aop:pointcut id="myPointcut" expression="execution(public void *.doSth())"></aop:pointcut>
                        <aop:before pointcut-ref="myPointcut" method="doBefore"></aop:before>
                    </aop:aspect>
                </aop:config>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值