在Spring中,Advice都是通过Interceptor来实现的,主要有以下几种:

1. 环绕Advice:

//例子摘自Spring reference
 
 
public 
    
  interface 
   MethodInterceptor  
  extends 
   Interceptor {
       Object invoke(MethodInvocation invocation)  
  throws 
   Throwable;
 }
 
  public 
    
  class 
   DebugInterceptor  
  implements 
   MethodInterceptor {

      
  public 
   Object invoke(MethodInvocation invocation)  
  throws 
   Throwable {
         System.out.println( 
  " 
  Before: invocation=[ 
  " 
    
  + 
   invocation  
  + 
    
  " 
  ] 
  " 
  );  //(1)
         Object rval  
  = 
   invocation.proceed();
         System.out.println( 
  " 
  Invocation returned 
  " 
  );  //(2)
          
  return 
   rval;
     }
 }


 

      环绕advice类似一个拦截器链,这个拦截器链的中心就是被拦截的方法。在程序(1)(2)我们可以加入我们自己的代码,以表示在方法执行前后我们需要干什么。invocation.proceed()方法运行指向连接点的拦截器链并返回proceed()的结果。

2. Before Advice

public 
    
  interface 
   MethodBeforeAdvice  
  extends 
   BeforeAdvice {
      
  void 
   before(Method m, Object[] args, Object target)  
  throws 
   Throwable;
 }


 

before 通知。它不需要 MethodInvocation对象,因为它只是在进入方法之前被调用。before advice的一个主要优点是它不需要调用proceed()方法,因此就不会发生 无意间运行拦截器链失败的情况。

3. After advice

 

public 
    
  interface 
   AfterReturningAdvice  
  extends 
   Advice {
      
  void 
   afterReturning(Object returnValue, Method m, Object[] args, Object target)  
  throws 
   Throwable;
 }

 

       一个After advice可以访问返回值(但不能进行修改),被调用方法,方法参数以及目标对象。

4.Throws Advice

 

// 
  ThrowsAdvice 是一个空接口,起标识作用 
  
 
  public 
    
  interface 
   ThrowsAdvice  
  extends 
   Advice {

 }
 
  // 
  所给对象必须实现一个或者多个针对特定类型的异常通知方法,格式如下 
  
 
  afterThrowing([Method], [args], [target], subclassOfThrowable)
 
  // 
  只有最后一个参数是必须的。因此异常通知方法对方法及参数的需求,方法的签名将从一到四个参数之间变化。


 

       最后还有一个是introduction advice,这个我想什么时候自己单独做个例子理解一下。

       做了个例子如下,想像一个用户登录场景:在登录之前,我们对其输入的用户名进行有效性检查;登录成功后,我们记上用户登录次数;如果登录失败,则进行异常处理。实现代码如下:

 

package 
   com.learn.spring.test.advisor;
 //登录的业务代码
 
  public 
    
  interface 
   LoginService {
      
  void 
   login(String name, String password)  
  throws 
   UnauthorityException;
 }

 
  public 
    
  class 
   LoginServiceImpl  
  implements 
   LoginService {

      
  public 
    
  void 
   login(String name, String password)  
  throws 
   UnauthorityException {
             check(name, password);
             System.err.println(name  
  + 
    
  " 
   is logining system... 
  " 
  );
     }
     
      
  private 
    
  void 
   check(String name, String password)  
  throws 
   UnauthorityException {
              
  if 
  ( 
  " 
  myyate 
  " 
  .equals(name)  
  && 
    
  " 
  pass 
  " 
  .equals(password) ) {
                      System.err.println(name  
  + 
    
  " 
   passed check.... 
  " 
  );
             }  
  else 
   {
                      
  throw 
    
  new 
   UnauthorityException( 
  " 
  invalid password 
  " 
  );
             }
     }
 }


//用户名检查 拦截器



public 
    
  class 
   LoginNameCheckInterceptor  
  implements 
   MethodBeforeAdvice {

      
  public 
    
  void 
   before(Method method, Object[] args, Object target)  
  throws 
   Throwable {
          System.err.println( 
  " 
  check user's name is valid? 
  " 
  );
           
  if 
  (args[ 
  0 
  ]  
  == 
    
  null 
    
  || 
    
  "" 
  .equals(args[ 
  0 
  ].toString().trim())) {
                 
  throw 
    
  new 
   IllegalArgumentException();
          }
     }
 }

 


// 
  用户登录次数统计拦截器 
  
 
  public 
    
  class 
   LoginCountInterceptor  
  implements 
   AfterReturningAdvice ...{

      
  public 
    
  void 
   afterReturning(Object returnValue, Method method, Object[] args, Object target)  
  throws 
   Throwable ...{
     System.err.println( 
  " 
  Counting the login counts of  
  " 
    
  + 
   args[ 
  0 
  ]);
     }
 }

 


//异常处理拦截器
 
 
public 
    
  class 
   ExceptionThrowInterceptor  
  implements 
   ThrowsAdvice {
     
      
  public 
    
  void 
   afterThrowing(Method m, Object[] args, Object target, IllegalArgumentException ex)  
  throws 
   Throwable {
     System.err.println( 
  " 
  Login name is wrong, exception:  
  " 
    
  + 
   ex);
     }
     
      
  public 
    
  void 
   afterThrowing(Method m, Object[] args, Object target, UnauthorityException ex) {
        System.err.println(target.getClass()  
  + 
    
  " 
  . 
  " 
    
  + 
   m.getName()  
  + 
   
             
  " 
  () throw a exception:  
  " 
    
  + 
   ex.getMessage());
     }
 }


 

配置文件如下:

 

<? 
  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" 
  
    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.0.xsd
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd" 
  > 
  

     
  < 
  bean  
  id 
  ="loginServiceTarget" 
  
        class 
  ="com.learn.spring.test.advisor.LoginServiceImpl" 
  /> 
  
        
     
  < 
  bean  
  id 
  ="loginNameCheckInterceptor" 
  
        class 
  ="com.learn.spring.test.advisor.LoginNameCheckInterceptor" 
  /> 
  
         
  <!-- 
   
    <bean id="loginCheckInterceptor"
        class="com.learn.spring.test.advisor.LoginCheckInterceptor"/>
          
  --> 
  
     
  < 
  bean  
  id 
  ="loginCountInterceptor" 
  
        class 
  ="com.learn.spring.test.advisor.LoginCountInterceptor" 
  /> 
  
     
  < 
  bean  
  id 
  ="exceptionThrowInterceptor" 
  
        class 
  ="com.learn.spring.test.advisor.ExceptionThrowInterceptor" 
  /> 
  
        
     
  < 
  bean  
  id 
  ="loginService" 
   class 
  ="org.springframework.aop.framework.ProxyFactoryBean" 
  > 
  
         
  < 
  property  
  name 
  ="target" 
  >< 
  ref  
  local 
  ="loginServiceTarget" 
  /></ 
  property 
  > 
  
         
  < 
  property  
  name 
  ="proxyInterfaces" 
  > 
  
             
  < 
  list 
  > 
  
                 
  < 
  value 
  > 
  com.learn.spring.test.advisor.LoginService 
  </ 
  value 
  > 
  
             
  </ 
  list 
  > 
  
         
  </ 
  property 
  > 
  
         
  < 
  property  
  name 
  ="interceptorNames" 
  > 
  
             
  < 
  list 
  > 
  
                 
  < 
  value 
  > 
  loginNameCheckInterceptor 
  </ 
  value 
  > 
  
                 
  < 
  value 
  > 
  loginCountInterceptor 
  </ 
  value 
  > 
  
                 
  < 
  value 
  > 
  exceptionThrowInterceptor 
  </ 
  value 
  > 
  
             
  </ 
  list 
  > 
  
         
  </ 
  property 
  > 
  
     
  </ 
  bean 
  > 
  
 
  </ 
  beans 
  > 
 
测试代码运行:
 
 
public     
  class 
   Test {

        public 
    
  static 
    
  void 
   main(String[] args)  
  throws 
   Exception {
         BeanFactory bf    = 
   
             BeanFactoryFactory.getBeanFactory(   " 
  beans.xml 
  " 
  , Test. 
  class 
  );
         LoginService ls    = 
   (LoginService) bf.getBean( 
  " 
  loginService 
  " 
  );
         ls.login(   " 
  myyate 
  " 
  ,  
  " 
  pass 
  " 
  );
     }
 }

 

输出结果:

 


check user's name is valid?
 myyate passed check   .... 
  
 myyate is logining system   ... 
  
 Counting the login counts of myyate