透析Spring2---第三章试读

 
第 3章 Spring的AOP实现
    3.1 正则表达式简介
3.2 认识AOP
3.2.1 代理机制
 3.2.2 AOP中的常用术语
3.3 传统的 AOP支持
3.3.1 前置通知 Before Advice
3.3.2 后置通知 After Advice
3.3.3 环绕通知 Around Advice
3.3.4 异常通知 Throw Advice
3.3.5 NameMatchMethodPointAdvisor
3.3.6 RegexpMethodPointcutAdvisor
3.3.7 DefaultPointcutAdvisor
3.3.8 引介
3.4 Spring 2.0中的 AOP
   3.4.1 Spring2.0中的 Pointcut定义
3.4.2 基于 XML Schema的前置通知
 3.4.3 基于 Annotation的前置通知
 3.4.4 基于 XML Schema的后置通知
 3.4.5 基于 Annotation的后置通知
 3.4.6 基于 XML Schema的环绕通知
 3.4.7 基于 Annotation的环绕通知
 3.4.8 基于 XML Schema的异常通知
 3.4.9 基于 Annotation的异常通知
      3.4.10 SpringAOP综合运用之超级玛丽完结篇
 3.5 小结

试读部分:

3.4 Spring 2.0中的AOP

 

 Spring2.0中除了支持 3.3节中讲述的传统的AOP支持,还提供了2种实现AOP的方式:
1、基于 XML的配置,使用基于Schema的XML配置来完成AOP,而且Advice也不用再实现任何其他特定的接口。
2、使用 JDK5的注释来完成AOP的实现,只需要一个简单的标签就完成了AOP的整个过程。
 
3.4.1 Spring2.0 中的Pointcut定义
     Spring2.0中的切入点 Pointcut的定义有2种方式,表达式配置和Annotation配置,下面具体讲解。
    1、表达式
     Spring2.0中的 Pointcut的定义支持的关键字有:execution(方法执行的连接点,
这是 Spring 中最主要的切入点指定者),within(限定匹配特定类型的连接点),this(连接点本身),target(连接点目标对象),arg(连接点参数)等,表达式的定义如下格式:
  execution(modifiers-pattern?
ret-type-pattern
declaring-type-pattern?
name-pattern(param-pattern)
throws-pattern?)
 
有“ ?”号的部分表示可省略的,modifers-pattern 表示修饰符如 public、protected 等,
ret-type-pattern 表示方法返回类型, declaring-type-pattern 代表特定的类,name-pattern 代表方法名称,param-pattern表示参数,throws-pattern表示抛出的异常。在切入点表达式中,可以使用*来代表任意字符,用..来表示任意个参数(注意这里不是正则表达式),比喻前面的
  execution(void spring.chapter3.proxy.Component.business*(..))
就表示执行spring.chapter3.proxy.Component中所有business开头的方法,这里的省略了第一个参数,第二个参数为void,在很多情况下传回值可以用*表示所有传回值均匹配,第三个参数这里指定了类spring.chapter3.proxy.Component,第四个参数为business*表示所有business开头的方法,这里方法的参数为(..),表示0个或者任意个参数,也可以使用*来指定任意参数,比如business*(*,String),表示2个参数,第一个为任意类型,第二个为String类型,同时还可以使用within关键字来表示,例如within(spring.chapter3.proxy.*)表示spring.chapter3.proxy包下的任何方法,由于within用的比较少,同时功能也有所局限,这里不再花太多的篇幅介绍。
   2、Annotation表达式
   基于JDK5.0以上我们还可以使用Annotation来配置切入点,表达式写法和前面一样,只不过这里不再需要使用配置文件来声明表达式了,直接使用 @Pointcut("execution()")就可以表示一个切入点了,以后在需要应用该切入点的时候就可以使用其标识的方法了。
比如:
  @Pointcut("execution(void spring.chapter3.proxy.Component.business*(..))")
public void beforePointcut(){}
表示在spring.chapter3.proxy.Component中所有business开头的方法这样一个切入点,在执行前置通知或者其他需要使用的时候直接使用:
 @before( "beforePointcut")
也就相当于@before( "execution(void spring.chapter3.proxy.Component.business*(..))")
 
3.4.2 基于XML Schema的前置通知
 Spring2.0提供了 Schema来通过配置文件解决了前置通知的限定接口,以改写3.3.1中的实例来讲解, AdviceBeforeComponent 不再需要实现 MethodBeforeAdvice 接口,改后的代码如下:
package  spring.chapter3.aop.schema;
publicclass AdviceBeforeComponent 
{
   publicvoid before()
{
     System.out.println(
"用户验证");
        }

}

这里的代码更加简介, before() 方法是自己定义的,可以任意定义方法名,方法可以接口 JoinPoint 作为参数,也可以不用任何参数,接着修改 advice.xml 配置文件如下:
<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>
    
< aop:config >
       
< aop:pointcut  id ="beforePointcut"
           expression
="execution(* spring.chapter3.proxy.IComponent.*(..))"   />
       
< aop:aspect  id ="before"  ref ="beforeAdvice" >
           
< aop:before  pointcut-ref ="beforePointcut"  method ="before"   />
       
</ aop:aspect >
    
</ aop:config >
    
< bean  id ="beforeAdvice"
       class
="spring.chapter3.aop.schema.AdviceBeforeComponent"   />
    
< bean  id ="component"  class ="spring.chapter3.proxy.Component"   />
</ beans >
首先加入schema的命名空间,然后就可以使用<aop:config>标签来配置了,在<aop:config>中首先定义了一个<aop:pointcut>这样就pointcut单独提出去来便于后面的使用,<aop:pointcut>相当于一个bean的配置,只是他只在<aop:config>范围有效,这里要注意的是正则表达式
execution(* spring.chapter3.proxy.IComponent.*(..))中的“*”和后面的表达式间要有个空格,否则会提示正则表达式错误,<aop:aspect>表示一个切面的定义,该切面引用beforeAdvice这个bean作为通知,<aop:before>表示一个前置通知的定义,该通知的规则引用beforePointcut这个切入点的表达式,method表示要引用的beforeAdvice中的before方法。
 
<aop:config>配置规则如下:
< aop:config >  
< aop:pointcut  id ="somePointcut"  expression ="" />  
< aop:advisor  id ="someAdvisor"  pointcut-ref =""  advice-ref ="" />  
< aop:aspect  id ="someAspect"  ref ="someBean" >  
< aop:adviceType  id ="someAdvice"  ... />  
</ aop:aspect >  
</ aop:config >  
针对上面的代码编写一个测试文件:
package  spring.chapter3.aop.schema;
import  org.springframework.context.ApplicationContext;
import  org.springframework.context.support.ClassPathXmlApplicationContext;
import  spring.chapter3.proxy.IComponent;
publicclass TestSchema 
{
    publicstaticvoid main(String[] args) 
{
       ApplicationContext context 
= new ClassPathXmlApplicationContext(
              
"spring/chapter3/aop/schema/advice.xml");
       IComponent component 
= (IComponent) context.getBean("component");
       component.bussiness1();
       component.bussiness2();
       component.bussiness3();
    }

}

运行结果如下:
  用户验证
业务 1
用户验证
业务 2
用户验证
业务 3
,达到预先效果,在每个 business 方法前均执行了用户验证 , 这里要注意的是:除了直接引用 spring.jar 外,还需要 aspectweaver.jar asm-*.jar asm-commons-*.jar
3.4.3 基于Annotation的前置通知
  Spring2.0结合 JDK5及以上版本,还提供了Annotation设置AOP的Advice,避免了XML的配置,更加简化了AOP实现,这里将3.4.2节中的示例改为Annotation配置AOP,首先修改 AdviceBeforeComponent 如下:
 
package  spring.chapter3.aop.schema;
import  org.aspectj.lang.annotation.Aspect;
import  org.aspectj.lang.annotation.Before;
@Aspect
public   class  AdviceBeforeComponent  {
    @Before(
"execution(* spring.chapter3.proxy.IComponent.*(..))")
  
public void before(){
      System.out.println(
"用户验证");
        }

}

@Aspect 标签表示将该类设置为一个 Aspect @Before 标签表示该方法在是一个前置通知,他遵守的规则是 execution(* spring.chapter3.proxy.IComponent.*(..)),也就是 spring.chapter3.proxy.Icomponent接口中的所有方法,接着修改一下XML配置文件如下:
<? xml version="1.0" encoding="UTF-8" ?>
< beans  xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop
="http://www.springframework.org/schema/aop"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.0.xsd 
     http://www.springframework.org/schema/aop 
     http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
>
    
< aop:aspectj-autoproxy  />
    
< bean  id ="beforeAdvice"
       class
="spring.chapter3.aop.schema.AdviceBeforeComponent"   />
    
< bean  id ="component"  class ="spring.chapter3.proxy.Component"   />
</ beans >
这里没有了前面的 <aop:config> 等配置,只有一个 <aop:aspectj-autoproxy/> 表示自动进行代理,其余的一切你都不用管了,交给 Spring 就是了,从这个例子可以看出基于 Annotation AOP 配置是最简化的,但是他使用了 @Aspect 等标签,这样给系统造成了一定的耦合,在实际应用中药选择哪个完全取决于个人意向。
本书近期由电子工业出版社出版!敬请关注!谢谢
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值