Spring中的AOP配置

基于Schema的AOP从Spring2.0之后通过“aop”命名空间来定义切面、切入点及声明通知。

    在Spring配置文件中,所以AOP相关定义必须放在<aop:config>标签下,该标签下可以有<aop:pointcut>、<aop:advisor>、<aop:aspect>标签,配置顺序不可变。

  • <aop:pointcut>:用来定义切入点,该切入点可以重用;
  • <aop:advisor>:用来定义只有一个通知和一个切入点的切面;
  • <aop:aspect>:用来定义切面,该切面可以包含多个切入点和通知,而且标签内部的通知和切入点定义是无序的;和advisor的区别就在此,advisor只包含一个通知和一个切入点。

 

 

6.3.1  声明切面

    切面就是包含切入点和通知的对象,在Spring容器中将被定义为一个Bean,Schema方式的切面需要一个切面支持Bean,该支持Bean的字段和方法提供了切面的状态和行为信息,并通过配置方式来指定切入点和通知实现。

 

    切面使用<aop:aspect>标签指定,ref属性用来引用切面支持Bean。

 

    切面支持Bean“aspectSupportBean”跟普通Bean完全一样使用,切面使用“ref”属性引用它。

6.3.2  声明切入点

    切入点在Spring中也是一个Bean,Bean定义方式可以有很三种方式:

    1)在<aop:config>标签下使用<aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,对于需要共享使用的切入点最好使用该方式,该切入点使用id属性指定Bean名字,在通知定义时使用pointcut-ref属性通过该id引用切入点,expression属性指定切入点表达式:

 

java代码:
  1. <aop:config> 
  2.  <aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/>  
  3.  <aop:aspect ref="aspectSupportBean">  
  4.     <aop:before pointcut-ref="pointcut" method="before"/>  
  5.  </aop:aspect>  
  6. </aop:config>  

 

    2)在<aop:aspect>标签下使用<aop:pointcut>声明一个切入点Bean,该切入点可以被多个切面使用,但一般该切入点只被该切面使用,当然也可以被其他切面使用,但最好不要那样使用,该切入点使用id属性指定Bean名字,在通知定义时使用pointcut-ref属性通过该id引用切入点,expression属性指定切入点表达式:

 

java代码:
  1. <aop:config>  
  2.  <aop:aspect ref="aspectSupportBean">  
  3.     <aop:pointcut id=" pointcut" expression="execution(* cn.javass..*.*(..))"/>  
  4.     <aop:before pointcut-ref="pointcut" method="before"/>  
  5.  </aop:aspect>  
  6. </aop:config>  

 

 

    3)匿名切入点Bean可以在声明通知时通过pointcut属性指定切入点表达式,该切入点是匿名切入点,只被该通知使用:

 

java代码:
  1. <aop:config>  
  2.  <aop:aspect ref="aspectSupportBean">  
  3.      <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterFinallyAdvice"/>  
  4.  </aop:aspect>  
  5. </aop:config>  

 

6.3.3  声明通知

基于Schema方式支持前边介绍的5中通知类型:

一、前置通知:在切入点选择的方法之前执行,通过<aop:aspect>标签下的<aop:before>标签声明:

 

java代码:
  1. <aop:before pointcut="切入点表达式"  pointcut-ref="切入点Bean引用"  
  2. method="前置通知实现方法名"  
  3. arg-names="前置通知实现方法参数列表参数名字"/>  

 

         pointcut和pointcut-ref二者选一,指定切入点;

         method指定前置通知实现方法名,如果是多态需要加上参数类型,多个用“,”隔开,如beforeAdvice(java.lang.String);

         arg-names指定通知实现方法的参数名字,多个用“,”分隔,可选,类似于【3.1.2 构造器注入】中的参数名注入限制:class文件中没生成变量调试信息是获取不到方法参数名字的,因此只有在类没生成变量调试信息时才需要使用arg-names属性来指定参数名,如arg-names="param"表示通知实现方法的参数列表的第一个参数名字为“param”。

 

首先在cn.javass.spring.chapter6.service.IhelloWorldService定义一个测试方法:

 

java代码:
  1. public void sayBefore(String param);  

 

其次在cn.javass.spring.chapter6.service.impl. HelloWorldService定义实现

 

java代码:
  1. @Override  
  2. public void sayBefore(String param) {  
  3.     System.out.println("============say " + param);  
  4. }  

 

 

第三在cn.javass.spring.chapter6.aop. HelloWorldAspect定义通知实现:

 

java代码:
  1. public void beforeAdvice(String param) {  
  2.     System.out.println("===========before advice param:" + param);  
  3. }  

 

最后在chapter6/advice.xml配置文件中进行如下配置:

 

java代码:
  1. <bean id="helloWorldService" class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>  
  2. <bean id="aspect" class="cn.javass.spring.chapter6.aop.HelloWorldAspect"/>  
  3. <aop:config>  
  4.     <aop:aspect ref="aspect">  
  5.         <aop:before pointcut="execution(* cn.javass..*.sayBefore(..)) and args(param)"   
  6.                            method="beforeAdvice(java.lang.String)"   
  7.                            arg-names="param"/>  
  8.     </aop:aspect>  
  9. </aop:config>  

 

 

测试代码cn.javass.spring.chapter6.AopTest:

 

java代码:
  1. @Test  
  2. public void testSchemaBeforeAdvice(){  
  3.      System.out.println("======================================");  
  4.      ApplicationContext ctx = new ClassPathXmlApplicationContext("chapter6/advice.xml");  
  5.      IHelloWorldService helloworldService = ctx.getBean("helloWorldService", IHelloWorldService.class);  
  6.      helloworldService.sayBefore("before");  
  7.     System.out.println("======================================");  
  8. }  

 

将输入:

 
 

==========================================

===========before advice param:before

============say before

==========================================

 

转载于:https://www.cnblogs.com/tware-dsy/archive/2012/12/06/2804748.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值