在 Intellij Idea 环境下初探 Spring Core (二) 之 AOP

说说

在 Intellij Idea 环境下初探 Spring Core (一) 之 IoC/DI 中, 我学会了使用 Spring 的 IoC 功能. 这篇文字写的是 AOP 功能.

AOP 的几种形式

当一个方法要执行的时候, Spring AOP 可以在方法执行之前或之后添加额外的执行方法. Spring AOP支持四种形式的AOP.

  1. 在方法执行之前拦截
  2. 在方法执行之后拦截
  3. 在抛出异常的时候拦截
  4. 包括以上三种拦截的拦截

在 Intellij idea 中体验 Spring AOP

  • 继续使用 (一) 中的工程
  • 在 com.jecvay.springhello 包中添加一个类 HijeckBeforeHello, 代码如下. 这个类就是要通过AOP在HelloWorld类的任何一个方法运行之前插入一段显示 Hiject before Hello world! 的代码.
package com.tutorialspoint;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;

public class HijackBeforeHello implements MethodBeforeAdvice {
  @Override
  public void before(Method method, Object[] args, Object target)
         throws Throwable {
      System.out.println("Hiject before Hello world!");
  }
}
  • 配置 Beans.xml, 因为这里AOP使用的是 CGLIB 动态代理, 所以相应的要在Beans中配置一个代理. 在 前插入如下代码
<bean id="hijeckBeforeHello" class="com.tutorialspoint.HijackBeforeHello" />
    <bean id="helloServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="helloWorld" />
        <property name="interceptorNames">
            <list>
                <value>hijeckBeforeHello</value>
            </list>
        </property>
    </bean>
  • 修改 MainApp 类, 用代理替换原本 HelloWorld 类型的 obj 对象:
HelloWorld obj = (HelloWorld) context.getBean("helloServiceProxy");
    obj.getMsg();
    obj.getMsg();
    obj.getMsg();
  • 运行结果如下所示:
Hiject before Hello world!
Hello, Jecvay
Hiject before Hello world!
Hello, Jecvay
Hiject before Hello world!
Hello, Jecvay

Tips

  • 如果想在方法执行完毕后拦截, 只要写一个继承 MethodAfterAdvice 的类, 然后配置同样的 Bean 即可.
  • 如果想在方法抛出异常的时候拦截, 则继承 ThrowsAdvice 类, 要插入的方法的参数就是要拦截的异常对象.
  • 如果想在一个拦截器中拦下上述三种情况, 则继承 MethodInterceptor 类, before 的直接写在开头, after 的写在 methodInvocation.proceed(); 之后, 异常的直接写在 try … catch 的 catch 中.

其他

从工程结构来看, 尤其是 Beans.xml 的配置来看, Spring AOP 是建立在 IoC 的基础之上的. 在程序运行后, 由 Spring 框架来产生提供 AOP 的代理模块, 并注入到 main 方法中.

实现AOP的其他方法

Spring AOP + AspectJ 方案可以让我们基于注解实现 AOP, 非常方便.

http://www.mkyong.com/spring3/spring-aop-aspectj-annotation-example/