AOP基本术语
通知(advice):定义是切面的目标,功能。但是就我的感觉来说,这只是一个类似桥梁的中间件。因为在例子中的所有advice类,就指明了什么时候该做什么方法。不过就advice的字义来理解。它只是一个建议,建议什么时候执行吧。
连接点(joinpoint):书上的定义是应用通知的时机,书上的这个定义有点模糊。我是这么理解的,如果说一个系统中,应用切面编程的所有交点。在我脑海中,有这样一幅图片(是受了书上的突变的启发):其实编写一个软件,会有很多的逻辑流,他们相互的交织着一个软件才能完成一个工作。而连接点就是这些逻辑流的交点。
切入点(pointcut):一个连接点的子集,或者说集合。借用一个数据库的概念,就是形成一个“原子性”的接入点。这里就是形成了一条逻辑流上所有的点。
切面(Aspect):通知和切入点的集合
引入(Introduction):允许向现有的类添加新方法和属性。这个我总觉得和切面不搭界。
目标(Target):被通知的对象,也就是被切的对象
代理(Proxy):这估计和Spring实现AOP的方式有关。Spring是利用代理来完成的。这就是为了实现而形成的代理。
织入(Weaving):实现AOP的过程。
流程
整个的流程相当的简单,建议一个切面。这里的切面其实就是一个逻辑流。切面只是在业务中不是占主导地位,或者说不是主要功能,但是必须要存在的逻辑流。就好像书中的例子观众,我们都明白这些其实对于程序来说,并不是最重要的。没有观众也能演,没用身份验证程序同样能跑。但是没有了会变成另一样东西,没有观众的表演叫彩排。
然后是建立通知。其实就是建立其和其他逻辑流交叉的时候的连接点进行定义。我觉得这有点拗口。毕竟程序是死的,但是逻辑是活的。逻辑流的之间需要排好方法执行的先后,这就是通知的作用。
切入点。这个有点死。就是配置xml文档。
<!-- 切入点--> <bean id="audienceAdvisor" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor" > <property name="advice" ref="audienceAdvice"/> <property name="expression" value="execution(* *.perform*(..))"/> </bean>
其中,advice表示是刚才建立的通知者的类。而erpression可以说是真正的切入点。既执行的方法。
这里还有一个语法。第一个*代表的是返回值,然后空格,第二个星表示的是类名。dot然后就是方法名。这里为了方便,就大多数都用了*,表示代表全部。如果实际中,则是正常的名字。
最后设置代理。其实这一段我明白,但是难以用言语表示其作用。在spring中,任何东西都需要一个bean。代理也是毅然。下面是xml文档。
<!-- 手动设置代理 --> <bean id="dukeTarget" class="geniusgame.PoeticJuggler"> <constructor-arg value="15"/> <constructor-arg ref="sonnet29"/> </bean> <bean id="dukeproxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="dukeTarget"/> <property name="interceptorNames" value="audienceAdvisor"/> <property name="proxyInterfaces" value="geniusgame.Performer"/> </bean>
然后是自动代理,少了一个bean的设置。
<!-- 自动代理 <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>-->
纯粹的aop切面
理解了上面,这个只是一个形式而已。我就直接写xml配置文件了。
<aop:config> <aop:aspect ref="audience"> <aop:before method="takeSeats" pointcut="execution(* *.perform(..))" /> <aop:before method="turnoffCellPhones" pointcut="execution(* *.perform(..))" /> <aop:after-returning method="applaud" pointcut="execution(* *.perform(..))" /> <aop:after-throwing method="demandRefund" pointcut="execution(* *.perform(..))" /> </aop:aspect> <!-- <aop:advisor id="aa" advice-ref="audienceAdvice" pointcut="execution(* *.perform(..))" order="0"/> --> </aop:config>