Spring第五周

静态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实例化模式.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容