面向切面编程,针对的对象主要是类的方法。也就是说,当某个类(某些类)的某个方法(某些方法)进行一次包装。比如,权限控制,当执行某个方法时,首先判断是否具有某种权限。
这里的包装有两个前提:1,不修改原有类的任何代码;2,用来包装的代码是易插拔的。也就是说,对于某个方法,用于包装它的代码,可以随意地在其执行前/后执行。
 
三个概念:Advice,用于进行包装的类;pointcut,包装操作的切入点;Aspect,切面,一个切面应该包括,Advice和pointcut。
四种类型:Before Advice,After Advice,Around Advice,AfterThrowingAdvice。
 
Spring2.0在AOP控制上实现的非常简化。首先在applicationContext的配置文件中声明两个bean,一个是Advice,另一个是被切入的对象。
 
然后声明一个aspect,一个aspect指定切入的详细信息。
例如,
    <bean id="logBeforeAdvice" class="com.hc.test.LogBeforeAdvice"/>
    <bean id="helloSpeaker" class="com.hc.test.HelloSpeaker"/>
    <aop:config>
        <aop:aspect id="logging" ref="logAdvice">
            <aop:before pointcut="execution(* com.hc.test.IHello.*(..))" method="before"/>
        </aop:aspect>
    </aop:config>
其中<aop:aspect>指定一个切面,ref="logBeforeAdvice"是该切面所使用的类实例。
<aop:before>指定切面处于切入点之前。pointcut="execution(* com.hc.test.IHello.*(..))" method="before"/>指定切入点。method="before"指定该切面所使用的类实例中哪个方法将被执行。
 
HelloSpeaker.java
package com.hc.test;

public class HelloSpeaker implements IHello {
  public void sayHello() throws Exception {
    System.out.println("Hello baby !");
  }
  public void toHello() {
    System.out.println("to hello to you");
  }
}
 
IHello.java
package com.hc.test;

public interface IHello {
  public void sayHello() throws Exception;
    
  public void toHello();
}
LogAdvice
package com.hc.test;

import org.aspectj.lang.JoinPoint;

public class LogAdvice {
  public void before(JoinPoint jointPoint) {
    System.out.println("........the before content of logging.......");
  }
}
在spring 容器中获得一个HelloSpeaker对象,并执行其sayHello()和toHello()方法。
执行结果如下所示。
........the before content of logging.......
Hello baby !
........the before content of logging.......
to hello to you
 
对于AfterAdvice、AroundAdvice和After Throwing Advice示例如下所示。
LogAdvice.java
package com.hc.test;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class LogAdvice {
  public void before(JoinPoint jointPoint) {
    System.out.println("........the before content of logging.......");
  }

  public void after(JoinPoint jointPoint) {
    System.out.println("........the after content of logging.......");
  }

  public Object around(ProceedingJoinPoint jointPoint) {
    System.out.println("........the begin around content of logging.......");
    Object retVal = null;
    try {
      retVal = jointPoint.proceed();
    } catch(Throwable throwable) {
        
    }
    System.out.println("........the end around content of logging.......");
    return retVal;
  }

  public void throwing(JoinPoint jointPoint, Throwable throwable) {
    System.out.println("........the trowing content of logging.......");
  }
}
HelloSpeaker.java
package com.hc.test;

public class HelloSpeaker implements IHello {
  public void test1() {
    System.out.println("Hello test 1 !");
  }

  public void test2() {
    System.out.println("Hello test 2 !");
  }

  public void test3() {
    System.out.println("Hello test 3 !");
  }

  public void test4() throws Exception {
    System.out.println("Hello test 4 !");
    throw new Exception();
  }
}
Spring配置文件
        <bean id="logBeforeAdvice" class="com.hc.test.LogAdvice"/>
        <bean id="helloSpeaker" class="com.hc.test.HelloSpeaker"/>
        <aop:config>
                <aop:aspect id="logging" ref="logBeforeAdvice">
                        <aop:before pointcut="execution(* com.hc.test.IHello.test1(..))" method="before"/>
                        <aop:after pointcut="execution(* com.hc.test.IHello.test2(..))" method="after"/>
                        <aop:around pointcut="execution(* com.hc.test.IHello.test3(..))" method="around"/>
                        <aop:after-throwing pointcut="execution(* com.hc.test.IHello.test4(..))" throwing="throwable" method="throwing"/>
                </aop:aspect>
        </aop:config>