SpringAOP

例子:SpringAOP

       编写目标类与切面类

publicclass Waiter{

     public String greetTo(String name) {

         System.out.println("这是目标类 name="+name);

         return"erer";

     }

}

publicclass SectionAdvice{

     publicvoid before(){

         System.out.println("before");

     }

     publicvoid after(){

         System.out.println("after");

     }

 

}

 

       Xml配置

<?xmlversion="1.0"encoding="UTF-8"?> 

<beansxmlns="http://www.springframework.org/schema/beans"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

  xmlns:aop="http://www.springframework.org/schema/aop"

  xmlns:tx="http://www.springframework.org/schema/tx"

  xsi:schemaLocation="

      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

     <!-- 目标类 -->

     <beanid="waiter"class="com.aop2.Waiter"/>

     <!-- 定义切面类 -->

     <beanid="sectionAdvice"class="com.aop2.SectionAdvice"/>

     <!-- 前置通知 -->

     <aop:config>

         <!-- 自动注入切面类  -->

         <aop:aspectref="sectionAdvice">

              <!-- 切点 -->

              <aop:pointcutid="service"expression="execution(* com.aop.Waiter.*(..))"/>

              <!--

                   execution(* com.aop2.*.*(..))"

                   第一个*代表所有的返回值类型

                   第二个*代表所有的类

                   第三个*代表类所有方法

                   最后一个..代表所有的参数。

              -->

              <!-- 通知 -->

              <aop:beforepointcut-ref="service"method="before"/>

              <aop:afterpointcut-ref="service"method="after"  />

         </aop:aspect>

     </aop:config>

</beans> 

 

前置通知(Before advice):在某连接点(JoinPoint)之前执行的通知,但这个通知不能阻止连接点前的执行。ApplicationContext中在<aop:aspect>里面使用<aop:before>元素进行声明。例如,TestAspect中的doBefore方法。

后置通知(After advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。ApplicationContext中在<aop:aspect>里面使用<aop:after>元素进行声明。例如,ServiceAspect中的returnAfter方法,所以Teser中调用UserService.delete抛出异常时,returnAfter方法仍然执行。

环绕通知(Around advice):包围一个连接点的通知,类似WebServlet规范中的FilterdoFilter方法。可以在方法的调用前后完成自定义的行为,也可以选择不执行。ApplicationContext中在<aop:aspect>里面使用<aop:around>元素进行声明。例如,ServiceAspect中的around方法。

抛出异常后通知(After throwing advice):在方法抛出异常退出时执行的通知。ApplicationContext中在<aop:aspect>里面使用<aop:after-throwing>元素进行声明。例如,ServiceAspect中的returnThrow方法。

返回后通知(After return advice):在某连接点正常完成后执行的通知,不包括抛出异常的情况。ApplicationContext中在<aop:aspect>里面使用<after-returning>元素进行声明。

AOP术语:

AOPAspect Oriented Programing 的简称,翻译:面向切面编程

       增强Advice):增强是织入到目标连接点上的一段程序代码。

       织入(Weaving):织入是将增强添加对目标具体连接点上的过程,AOP像一台织布机,将目标、增强通过AOP这台织布机天衣无缝地编织到一起。

       连接点(joinpoint):程序执行的某个特定位置:如类开始初始化前、类初始化后、类某个方法调用前、调用后、方法抛出异常后。

       切点:每个程序类都拥有多个连接点,如一个拥有两个方法的类,这两个方法都是连接点。但是这为数众多的连接点中,如何定位到某个感兴趣的连接点上呢?AOP通过切点定位特定连接点。一句话:切点就是指定的连接点。

       代理:一个类被AOP织入增强后,将产生了一个结果类,它是融合了原类和增强逻辑的代理类。根据不同的代理方法,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以我们可以采用调用原类相同的方式调用代理类。

       切面:切面由切点和增强组成,它既包括了增强的定义,也包括了连接点的定义。SpringAOP 就是负责实施切面的框架,它将切面所定义的增强织入到切点(指定的连接点)中。

 

 

为什么需要面向切面编程?

我们现在做的一些非业务,如:日志、事务、安全等都会写在业务代码中(也即是说,这些非业务类横切于业务类),但这些代码往往是重复,复制——粘贴式的代码会给程序的维护带来不便,AOP就实现了把这些业务需求与系统需求分开来做。这种解决的方式也称代理机制。

阅读更多

没有更多推荐了,返回首页