`
足至迹留
  • 浏览: 494773 次
  • 性别: Icon_minigender_1
  • 来自: OnePiece
社区版块
存档分类
最新评论

<4> 简记aop原理和使用

阅读更多
前面把IOC的主要内容都介绍完了,这篇就是另一个spring的核心:aop

在软件中,有些行为对大多数模块说都是通用的。如登录、日志、性能统计、安全和事务管理都是重要的事情又是公共的功能,与业务模块功能需要配合一起工作,如果把这些公共功能与业务功能模块交织在一起编码,则到处散乱,对代码的维护,修改,响应变化都不方便。
在程序开发中,散布于程序中多个地方的函数被称为“交叉事务”。应该把他们与一般的业务逻辑分开(但实际经常是直接嵌入的),把这些交叉事务与业务逻辑分开正是面向切面编程(即AOP)的作用所在。

一、 AOP术语
Aop的术语都不太直观理解,这完全没有关系,可以先大概知道这些概念,然后在实际应用中去理解。
1. 通知(advice)
就是切面(aspect,后面会介绍)要完成的功能,就是上面引文中提到的”交叉事务”。这些功能需要在指定的位置(就是下面要说的连接点)前(before)执行还是位置后(after)执行还是抛出异常后(throws)执行,这些都可以根据指定的时机在指定的位置来完成特定的功能。
有5种类型的通知
1) Before: org.springframework.aop.MethodBeforeAdvice
2) After-returning: org.springframework.aop.AfterReturningAdvice
3) After-throwing: org.springframework.aop.ThrowsAdvice
4) Around:org.aopalliance.intercept.MethodInterceptor
5) Introduction: org.springframework.aop.IntroductionInterceptor
除了org.aopalliance.intercept.MethodInterceptor外这些接口都是spring框架的。Around通知相当于before,ater-returning和after-throwing三者结合的通知。

2. 连接点(Joinpoint)
就是要把上面的通知功能应用到哪个地方,这个地方可以是指定的方法被调用时,异常被抛出时等。也可以说,通知是发生在特定的连接点上的。Sping只支持方法连接点,如AspectJ和Jboss不仅提供方法连接点还可以是字段和构造器连接点。
3. 切入点(Pointcut)
指定一个通知将被引发的一系列连接点的集合。也就是切入点把连接点聚集起来,指明了要在哪些连接点上执行通知功能。 AOP框架必须允许开发者指定切入点,比如可以通过正则表达式指定。切入点分静态切入点和动态切入点,动态切入点比静态切入点的演算代价高很多(这两种切入点后面会再提到)。
4. 切面(Aspect)
    切面是通知和切入点的结合。指明了在何时何地执行什么功能。可以用用Spring的 Advisor或拦截器实现,也就是提供通知功能的类。
5. 目标(target)
包含连接点的对象。也被称作 被通知或被代理对象。
6. 代理(proxy)
AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。如果目标对象实现的是一个接口,则会采用JDK动态代理,如果目标类不是一个接口而是类,则会使用CGLIB生成目标类的一个子类作为代理。注意,被标记为final的方法不能被通知(因为final方法不能被子类重写)。
7. 织入(weaving)
是把切面(aspect)应用到目标对象(target)来创建新的代理对象(proxy)的过程。
在目标对象的生命周期中有多个时机可以发生织入过程:
1) 编译时。需要特殊的编译器,AspectJ的织入编译器就是这种方式。
2) 类加载时。需要特殊的ClassLoader.AspectJ 5的“加载时织入(LTW)”就是这种方式。
3) 运行时。一般情况下,在织入切面时,AOP容器会动态创建一个代理对象。Spring就是这种方式。Spring2.0从AspectJ项目借鉴了很多对AOP的支持,Spring对AOP的支持比AspectJ要弱,只支持方法的注入。

二、 创建通知,切入点,切面,代理
下面分别介绍spring框架如何支持aop的,需要执行哪些步骤。也方便使用时理解配置,或实现自定义的aop功能。
1. 创建通知:只要让切面类(包含通知功能的类)实现上面5种通知类型的接口,就可以分别实现相应功能的通知。
2. 创建切入点:
Spring提供了几种不同类型的切点,其中两种最有用的是正则表达式切点和AspectJ表达式切点。
1) 声明正则表达式切点
Jdk1.4之后都是使用org.springframework.aop.support.JdkRegexpMethodPointcut类定义:
<bean id=”performPointcut”
     class=” org.springframework.aop.support.JdkRegexpMethodPointcut”>
<property name=”pattern” value=”.*perform” />
        </bean>
        然后联合通知和切入点
        <bean id=”audienceAdvisor”
class=”org.springframework.aop.support.DefaultPointcutAdvisor”>
<property name=”advice” ref=”audienceAdvice” />--通知类
<property name=”pointcut” ref=”performPointcut” />--切入点
</bean>
audienceAdvisor就是一个完整的切面了。
还有一个简单点的写法,利用RegexpMethodPointcutAdvisor创建切面。
<bean id=”audienceAdvisor”
Class=”org.springframework.aop.support.RegexpMethodPointcutAdvisor”>
<property name=”advice” ref=” audienceAdvice” />
<property name=”pattern” value=”.*perform” />---这里可以直接定义切入点表达式,不需要再引用切入点的bean了。
</bean>

2)但spring中更加常用的是AspectJ 切点表达式,要利用
AspectJExpressionPointcutAdvisor:
<bean id=”audienceAdvisor”
Class=”org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor” />
<property name=”advice” ref=”audienceAdvice” />
<property name=”expression” value=”execution(*.*.perform(..))” />
</bean>
注:关于AspectJ切点表达式可以参考:
http://sishuok.com/forum/posts/list/281.html

到现在还没有完成aop功能,切面在spring里是以代理方式实现的,还需要代理bean(proxy)才行.可以使用ProxyFactoryBean实现。
3. 创建代理
<bean id=”dukeTarget” class=”com.springinaction.PoeticJuggler”
autowire=”constructor”>
<constructor-arg ref=”songnet29” />
</bean>----这里定义的是target
<bean id=”duke”
Class=”org.springframework.aop.framework.ProxyFactoryBean”>
<property name=”target” ref=”dukeTarget” />--指明target
<property name=”interceptorNames” value=”audienceAdvisor” />--指明通知
<property name=”proxyInterfaces” value=”com.springinaction.Performer” />
</bean>--这里定义的是proxy

至此,一个完整的spring AOP功能就完成了,最后是通过创建代理bean来应用切面功能。配置完我们发现这个过程很繁琐,所有的元素都需要配置。不用担心,上面只是分解了spring实现aop需要做的所有步骤,为了理解原理,实际使用时我们可以简化配置,比如让spring自动代理被通知的bean.

4.自动代理
针对上面的《创建代理》步骤,我们可以用自动代理简化,实现自动代理bean的方式有两种
1) 基于spring上下文里声明的通知者bean的基本自动代理:即使用xml配置切点表达式,决定哪个bean和哪个方法要被代理。
2) 基于@AspectJ注解。
这两种方式就是为了消除ProxyFactoryBean.

1. xml配置
查看上面的切入点表达式,里面有足够的信息决定哪个bean的哪个方法需要通知了,我们可以使用Spring提供的DefaultAdvisorAutoProxyCreator(是一种BeanPostProcessor)来自动检查切点是否匹配bean.
为了使用DefaultAdvisorAutoProxyCreator,只需要在spring上下文里声明如下<bean>:
<bean class=”org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator” />
这个bean不需要id,因为我们永远不会直接引用它,spring容器会自动识别这个BeanPostProcessor,利用它创建代理。这样就不需要配置ProxyFactoryBean了。

2. 自动代理 @AspectJ切面
1) 把包含通知的类声明为切面@Aspect
@Aspect         // 声明切面
Public class Audience
{
  @Pointcut(“execution(* *.perform(..))”) //定义切入点,只做定义使用,没有其他作用。
   Public void performance() {}

  @Before(“performance()”)  //定义Before通知
  Public void takeSets() {}
}




2) 然后只需要把切面类定义成一个普通bean. 为了支持自动创建代理bean,需要利用Spring提供的AnnotationAwareAspectJAutoProxyCreator,把它注册成一个bean.spring在aop命名空间提供了一个简单自定义配置元素:
<aop:aspectj-autoproxy />
这个需要在beans的命名空间提供支持:



切面的自动代理极大简化了spring切面的配置工作,同时也让程序透明化,隐藏了切面的很多细节。
至此上面所有内容都可以作为理解spring配置AOP的基础,是最原始的配置方式,也体现了spring处理的过程。下面讲的是目前用的最多的比较方便的配置方式(其实注解也使用的挺多的)。

三、 定义纯粹的POJO切面
使用ProxyFactoryBean配置有些欠优雅,即使使用自动代理配置,包括前面的通知、切入点都还是要配置成bean,整个aop配置不聚集,不直观。在spring2.0里新的xml配置元素体现了改进。Spring2.0在aop命名空间里提供了一些配置元素,简化了把类转化为切面的操作。



通过上面的理论基础,下面这个例子就很容易理解了:



另外还可以自定义AspectJ切面注入到Spring, 这个不常用,这里就不记录了。

最后推荐两篇博文跟本篇内容相关:
http://www.ibm.com/developerworks/cn/java/j-lo-springaopcglib/
http://docs.huihoo.com/spring/zh-cn/aop.html

关于Aspect依赖:
https://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/
http://blog.xuite.net/franky.chao/wretch/154513858
  • 大小: 78.9 KB
  • 大小: 112.5 KB
  • 大小: 32.3 KB
  • 大小: 64.5 KB
0
0
分享到:
评论
2 楼 足至迹留 2013-08-13  
中岛嘉兰 写道
不明觉厉,好抽象啊

你好,这部分确实不知道怎么讲才像白话一样好懂,可能文中例子给的比较少,看看文中给的链接可能会更好点。还有对自动创建代理那里可能需要看下上一篇的《高级bean装配》会好理解点。具体哪写的不好的或错误的地方请多多指正,谢谢~
1 楼 中岛嘉兰 2013-08-13  
不明觉厉,好抽象啊

相关推荐

    电梯模拟系统(数据结构)

    &lt;br&gt;&lt;br&gt;乘客可随时地进出于任何层。对于每个人来说,他有一个能容忍的最长等待时间,一旦等候电梯时间过长,他将放弃。&lt;br&gt;&lt;br&gt;模拟时钟从0开始,时间单位为0.1秒。人和电梯的各种动作均要消耗一定的时间单位(简记...

    [简单]log4jdbc-log4j2配置简记

    标题中的“log4jdbc-log4j2配置简记”指的是在Java开发中使用log4jdbc-log4j2库来监控和记录SQL查询的过程。log4jdbc是一个开源项目,它允许开发者通过日志系统来追踪数据库操作,而log4j2是log4j的升级版,提供了更...

    jsp标准语法中7大动作 简记(经典)

    4. **&lt;jsp:useBean&gt;** JSP使用这个动作查找或创建一个JavaBean实例。它可以在页面作用域、请求作用域、会话作用域或应用作用域中查找已存在的bean,或者如果未找到,就根据指定的类创建一个新的bean。 5. **&lt;jsp:...

    甘油间歇发酵酶催化非线性动力系统的强稳定性

    &lt;p&gt;以甘油生物转化生产1, 3-丙二醇(简记为1, 3-PD) 的间歇发酵酶催化过程为背景, 研究一类既无法求得解析解、又没有平衡点的非线性动力系统. 论述了该类系统关于初始状态的解集的紧性以及对应的线性变分系统基本矩阵...

    英语音标简记法-英语学习

    英语音标简记法是学习英语发音的重要工具,它帮助我们准确地读出单词,提升听力和口语能力。本文将详细介绍几种常见的英语音标简记方法,并通过举例帮助理解。 首先,我们来看“去尾法”。这种方法适用于那些以元音...

    练习简记第一期

    ### 练习简记第一期知识点总结 #### 练习1——聚函数 **题目描述:** 本题考察了SQL语言中的聚合函数及其使用规则。具体来说,题目给出了一条SQL查询语句,并询问该语句是否合法以及其含义。 **SQL语句:** ```...

    简记个人博客源码免费分享

    简记个人博客网站源码为博主现有博客网站,前端采用LayUI框架,此分享版本为asp + access。所有功能齐全,欢迎使用。 使用方法:上传至空间或服务器,通过IIS发布网站即可。 演示地址:...

    高中化学各简记规律.docx

    - 酸性强弱顺序:HClO4 &gt; HI &gt; HBr &gt; HCl &gt; HNO3 &gt; H2SO4 &gt; H2SO3 &gt; H3PO4 &gt; CH3COOH &gt; H2CO3 &gt; H2S &gt; HClO &gt; H2SiO3 &gt; Al(OH)3。 4. 金属焰色反应: - 钠燃烧呈现黄色,钾呈现紫色,钙为砖红色,锶洋红,锂紫红...

    原理图的绘制简记-原理图设计经验

    原理图设计经验分享 以下是对原理图设计经验的详细总结: 一、MCU的选型 在设计原理图时,首先需要选择合适的MCU。选择MCU需要考虑产品需求,...原理图设计需要考虑许多因素,需要设计师具备深入的电路知识和经验。

    CRC16原理及算法附带两种程序

    根据提供的文件信息,本文将详细解释CRC16的原理及其在ModBus和DLMS协议中的应用。 ### 一、CRC16基本原理 CRC (Cyclic Redundancy Check) 是一种用于检测数字通信中错误的方法。CRC16是一种特定的CRC实现方式,它...

    497476974884240简记.apk

    497476974884240简记.apk

    C语言优先级

    它们包括算术运算符(如+、-、*、/、%、&lt;&lt;、&gt;&gt;)、关系运算符(如&gt;、&gt;=、&lt;、&lt;=、==、!=)、按位与(&)、按位异或(^)、按位或(|)、逻辑与(&&)和逻辑或(||)。这些运算符大部分有从左向右的结合性,但是逻辑与...

    Java字符集编码简记

    例如,Maven在pom.xml文件中可以设置`&lt;project.build.sourceEncoding&gt;`属性来指定源代码的编码,这样在构建过程中就可以确保编译器使用正确的编码。 在实际工作中,我们还需要关注字符集编码在Web应用中的应用,如...

    17年软院计组试卷简记1

    这篇简记涵盖了计算机组成原理中的多个重要知识点,主要包括程序控制I/O...以上就是2017年软院计组试卷简记中涉及的主要知识点,涵盖了计算机系统的基础架构和工作原理。深入理解这些概念对于学习计算机科学至关重要。

    html+css pdf

    "&gt;欢迎来到尚硅谷学习&lt;/h1&gt;`。优点是可以快速添加样式,但缺点是书写繁琐、样式不能复用、并且没有体现出结构与样式分离的思想,不推荐大量使用。 2.内部样式:写在 HTML 页面内部,将所有的 CSS 代码提取出来,...

    简记个人博客网站源码 v2.10.01.rar

    【简记个人博客网站源码 v2.10.01.rar】是一个包含个人博客网站完整源码的压缩包,版本号为v2.10.01,它主要用于搭建和自定义个人博客平台。这个源码可能由前端界面、后端服务器逻辑以及数据库结构组成,适用于那些...

    usaco课文学习简记1

    这篇学习简记主要涵盖了四个章节,分别是Ad Hoc Problems(杂题)、Complete Search(完全搜索)、Greedy Algorithm(贪心算法)和More Search Techniques(更多搜索技术)。每个章节都讲解了相应的算法思想及其应用...

    计算机组成原理第二章2022优秀文档.ppt

    计算机组成原理第二章的ppt文档中详细介绍了计算机组成原理的第二章的内容,主要涉及到算术逻辑运算器(Arithmetic Logic Unit,简记为ALU)的组成和构造、并行加法器的设计、进位链的逻辑构造等内容。 一、算术...

    Jerkwin#Jerkwin.github.io#2014-02-23-GAMESS2013编译使用简记1

    title: GAMESS2013编译使用简记- 科2014-02-23 21:14:14 初稿2014-03-08 12:09:09 修订编译解压 tar -

Global site tag (gtag.js) - Google Analytics