探索Spring2.0中的AOP(一)

    首先从配置文件入手,看看Spring2.0是如何利用配置文件实现AOP的(从javaeye一位兄台的blog摘得http://iorit2003.iteye.com/blog/122534),然后再看看Spring2.0内部究竟是如何实现AOP功能的。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
     <bean id="kwikEMartTarget" class="demo.ApuKwikEMart">
     </bean>

     <!-- 方法调用前通知 -->
     <bean id="welcomeAdvice" class="demo.advice.WelcomeAdvice" />
     <!-- 方法调用后通知 -->
     <bean id="thankYouAdvice" class="demo.advice.ThankYouAdvice" />
     <!-- 环绕调用通知 -->
     <bean id="onePerCustomerInterceptor" class="demo.advice.OnePerCustomerInterceptor" />
     <!-- 异常调用通知 -->
     <bean id="kwikEmartExceptionAdvice" class="demo.advice.KwikEmartExceptionAdvice" />
    
     <bean id="kwikEMart" class="org.springframework.aop.framework.ProxyFactoryBean">
          <property name="proxyInterfaces" value="demo.KwikEMart" />
          <property name="interceptorNames">
               <list>
                    <value>welcomeAdvice</value>
                    <value>thankYouAdvice</value>
                    <value>onePerCustomerInterceptor</value>
                    <value>kwikEmartExceptionAdvice</value>
               </list>
          </property>
          <property name="target">
               <ref bean="kwikEMartTarget" />
          </property>
     </bean>

</beans>

配置文件不用多说,这里假设你了解Spring的配置文件applicationContext.xml.
你可以看到,AOP在上述配置文件中主要涉及三部分内容:
1.被编织(代理)的类
2.被编入的方法
3.编织(代理)类

下面逐个分析,首先看第一部分,也就是被编织类,在上述配置文件中是id为kwikEMartTarget的bean,其定义为:

public class ApuKwikEMart implements KwikEMart {

     public Cheese buyCheese(Customer customer) throws NoMoreCheeseException{
...
     }

     public Pepper buyPepper(Customer customer) throws NoMorePepperException{
...
     }

     public Squish buySquish(Customer customer) throws NoMoreSquishException{
...
     }
}

其实现的接口KwikEMart定义为:
public interface KwikEMart {
     Squish buySquish(Customer customer) throws KwikEMartException;
     Pepper buyPepper(Customer customer) throws KwikEMartException;
     Cheese buyCheese(Customer customer) throws KwikEMartException;
}

    类的具体实现内容暂且不必关心,只需要知道他实现了一个叫做KwikEMart的接口,其中定义了三个方法即可.

    接着看AOP在配置文件中的第二部分,被编入的方法. 被编入的分别被定义在id为welcomeAdvice,thankYouAdvice,onePerCustomerInterceptor和kwikEmartExceptionAdvice的四个类中,其定义分别为:
public class WelcomeAdvice implements MethodBeforeAdvice {

     public void before(Method method, Object[] args, Object target) throws Throwable {
         ...
     }
}

public class ThankYouAdvice implements AfterReturningAdvice {

     public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
...
     }
}

public class OnePerCustomerInterceptor implements MethodInterceptor {
    
     public Object invoke(MethodInvocation invoke) throws Throwable {
          ...
     }
}

public class KwikEmartExceptionAdvice implements ThrowsAdvice {

     public void afterThrowing(NoMoreSquishException e) {
         ...
     }
     public void afterThrowing(NoMoreCheeseException e) {
         ...
     }
     public void afterThrowing(NoMorePepperException e) {
...
     }
}

    我们同样不用关心方法的实现细节,只需要知道他们实现的接口即可。
在Spring2.0的AOP中,一共定义了四种类型的拦截器
1.前置拦截器: 在被织入的方法调用前执行,接口为MethodBeforeAdvice.
2.后置拦截器: 在被织入的方法调用后执行,接口为AfterReturningAdvice.
3.环绕拦截器: 在被织入的方法调用前后执行,接口为MethodInterceptor.
4.异常拦截器: 在被织入的方法抛出异常后执行,接口为ThrowsAdvice.
其中每一种拦截器都规定了实现其功能而必须实现的接口方法.

    配置文件中AOP相关的最后一部分也是最重要的一部分是配置编织(代理)类,在上述配置文件中是id为kwikEMart的bean,其类型是Spring中的类ProxyFactoryBean.
要对类ApuKwikEMart织入上述四个拦截器,还需要为ProxyFactoryBean配置几个属性,其中proxyInterfaces为被织入(代理)类kwikEMart的bean所实现的所有接口;interceptorNames为拦截器列表,在其中添加所需要织入的拦截器。

    经过上述配置,就可以将所配置的四个拦截器织入类kwikEMart中。

    觉得很神奇是吗,所有的奥秘就发生在ProxyFactoryBean中,就是他完成了所有的编织工作,下一篇中我们将一探ProxyFactoryBean的究竟,了解这个编织器是如何完成工作的。

to be continued...

你可能感兴趣的:(spring,AOP,bean,xml,Blog)