Spring AOP入门

这篇文章是我对一篇文章修改进行发布的,修改了许多我认为不容易理解的地方,同时也将格式改美观,以方便大家阅读。

我们只需要理解三个概念就可以编写AOP模块了。这三个概念是:advice,pointcut和advisor。
       advice :advice是你想向别别的程序内部不同的地方注入的代码。
       pointcut: 定义需要注入advice的位置。
       advisor:是advice和pointcut的装配器,是将advice注入主程序预定位置的代码

既然我们知道了需要使用advisor向主要代码中注入“不可见的”advice,那么让我们实现一个Spring AOP的例子。在这个例子中,我们将实现一个before advice,即这个advice的代码在目标方法被调用前开始执行。以下是这个before advice的实现代码:
package com.spring;

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;

public class TestBeforeAdvice implements MethodBeforeAdvice {
       /**需要向其他程序注入的代码*/
       public void  before(Method m, Object[] args, Object target)   
         throws Throwable {   
          System.out.println("before advice 需要其它程序中注入的代码,在被注入程序执行之前执行" );   
      }
}

在下面的BeanImpl类中,theMethod()是 目标方法 。它将在before advice执行完之后开始执行。
package com.spring;

public class BeanImpl implements Bean{
       public void theMethod() {
             /**被其他代码注入的代码*/
          System.out.println("theMethod() 注入代码执行之后执行");   
        }
}

类BeanImpl实现了下面的接口Bean:
package com.spring;

public interface Bean {  
         /**接口*/
        package com.spring; 
} 

虽然不是必须使用接口,但面向接口而不是面向实现编程是良好的编程实践,Spring也鼓励这样做。 

pointcut和advice的装配工作」是通过配置文件来实现,因此,接下来你只需编写主方法的Java代码:
package com.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class Main {
       public static void main(String[] args) {   
           //读取配置文件   
          ApplicationContext ctx   
              = new FileSystemXmlApplicationContext("springconfig.xml" );   
       
           //实例化对象   
          Bean x = (Bean) ctx.getBean( "bean" );   
       
           // 执行bean里的theMethod方法   
          x.theMethod();   
      } 
}

由Main类可以知道,整个程序的的执行,是从读取和处理配置文件springconfig.xml开始的。接下来我们来创建它,  这个配置文件将作为粘合程序不同部分的“胶水”。读入和处理配置文件后,我们会得到一个创建工厂ctx。任何一个Spring管理的对象都必须通过这个工厂来创建。对象通过工厂创建后便可正常使用。 

<? xml version ="1.0" encoding= "UTF-8" ?>   
<! DOCTYPE beans PUBLIC   "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" >    
 
< beans>    
   <!--CONFIG,配置-->   
   <bean id= "bean" class ="org.springframework.aop.framework.ProxyFactoryBean" >
        <!-- 代理接口 -->      
     <property name= "proxyInterfaces">
       <value > com.spring.Bean</ value >   
     </property >
       <!-- 目标 -->    
     <property name= "target">    
       <ref local= "beanTarget"/>    
     </property >   
      <!-- 拦截器(advisor:装载器) -->     
     <property name= "interceptorNames">    
       <list >    
         < value> theAdvisor </value >    
       </list >    
     </property >    
   </bean >    
 
   <!--CLASS 目标代码-->   
   <bean id= "beanTarget" class ="com.spring.BeanImpl" />    
 
   <!--ADVISOR 装配器-->   
   <!--Note: An advisor assembles pointcut and advice-->    
   <bean id= "theAdvisor" class ="org.springframework.aop.support.RegexpMethodPointcutAdvisor" >    
     <property name= "advice">    
       <ref local= "theBeforeAdvice"/>    
     </property >    
     <property name= "pattern">    
       <value > com\.spring\.Bean\.theMethod </value >    
     </property >    
   </bean >    
 
   <!--ADVICE 被注入代码-->    
   <bean id= "theBeforeAdvice" class ="com.spring.TestBeforeAdvice" />    
</ beans>
四个bean定义的次序并不重要。

我们现在有了一个advice,一个advisor,一个主程序类和一个配置好的接口。通过工厂ctx,这个接口返回自己本身实现的一个引用。 

BeanImpl和TestBeforeAdvice都是直接配置。我们用一个唯一的ID(如:
id =   "beanTarget"    id =  " theBeforeAdvice "   ) 创建一个bean元素,并指定了一个实现类。这就是全部的工作。  

advisor通过Spring framework提供的一个RegexMethodPointcutAdvisor类来实现。我们用advisor的一个属性来指定它所需的advice-bean。第二个属性则用正则表达式定义了pointcut,确保良好的性能和易读性。 

最后配置的是bean,它可以通过一个工厂来创建。bean的定义看起来比实际上要复杂。bean是ProxyFactoryBean的一个实现,它是Spring framework的一部分。这个bean的行为通过一下的三个属性来定义: 
  • 属性proxyInterface定义了接口类。 
  • 属性target指向本地配置的一个bean,这个bean返回一个接口的实现。 
  • 属性interceptorNames是唯一允许定义一个值列表的属性。这个列表包含所有需要在beanTarget上执行的advisor。注意,advisor列表的次序是非常重要的。
需要引入的jar包:spring.jarcommons-logging.jar
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值