|
下面以JdkRegexpMethodPointcut为例,通过一个完整的范例展示如何使用静态切入点(完整工程代码见例程4.3)。在工程中我们定义一个People类和一个切面,并将他们在Spring xml配置文件中联系起来。当People对象执行我们切入点中定义的方法时,前置装备LogerPeople将会给出相应的提示信息。
新建一个工程AOP_Test4.3,添加Spring开发库后,新建aop.test包。
创建目标类People,该类有speak、Running、Loving、died四个成员方法。代码如下:
1 package aop.test; 2 public class People{ 3 // 讲话 4 public void speak() { 5 System.out.println("Hello,我是People!"); 6 } 7 // 跑步 8 public void Running() { 9 System.out.println("我在跑……跑…………逃……"); 10 } 11 // 恋爱 12 public void Loving() { 13 System.out.println("我在和MM恋爱……别来打搅我!"); 14 } 15 // 死亡 16 public void died() { 17 System.out.println("完了,我死了"); 18 } 19 } 20 创建一个类名为LogerPeople的前置装备,它实现MethodBeforeAdvice接口,在before方法中利用Log4J输出相关信息,代码如下:
1 package aop.test; 2 3 import java.lang.reflect.Method; 4 5 import org.apache.commons.logging.Log; 6 import org.apache.commons.logging.LogFactory; 7 import org.springframework.aop.MethodBeforeAdvice; 8 9 public class LogerPeople implements MethodBeforeAdvice { 10 11 private static final Log log = LogFactory.getLog(LogerPeople.class); 12 13 public void before(Method method, Object[] args, Object target) 14 throws Throwable { 15 // 这里什么也不做,只是利用Log4J输出日志信息 16 log.info(target.getClass().getSimpleName() + "正在" + 17 method.getName()+ "!"); 18 } 19 } 20 再编写Spring配置文件,完成后如下:
1 2 3 4 5 6 7 class="org.springframework.aop.framework.ProxyFactoryBean"> 8 9 10 11 12 13 DefaultAdvisor 14
15 16 17 18 19 class="org.springframework.aop.support.DefaultPointcutAdvisor"> 20 21 22 23 24 25 class="org.springframework.aop.support.JdkRegexpMethodPointcut"> 26 27 28 .*spea.* 29 .*ing 30 .*di.* 31
32 33 34 35 36 为了让ProxyFactoryBean使用我们定义的JdkRegexpMethodPointcut而不是默认的Pointcut,我们需要配置一个切入点配置器PointcutAdvisor,其advice属性指定装备,Pointcut属性指定切入点。然后再将该切入点配置器注入给ProxyFactoryBean.各个Bean的依赖关系和说明如下:

图4.4 ProxyFactoryBean代理生成
在JdkRegexpMethodPointcut中,我们使用了它两个属性patterns和excludedPattern:patterns利用正则表达式指定了我们要监视的方法这里是包含了所有的方法;excludedPattern指定了我们要排除的方法,这里指定了以Run开头的方法。
注意:
1)“。*spea.*”表示所有名字以spea开头的方法,例程中是指speak方法;
2)“。*ing” 表示所有名字以ing结束的方法,例程中是指Running和Loving方法;
3)“。*di.*” 表示所有名字以di开头的方法,例程中是指died方法;
4)“。*Run.*” 表示所有名字以Run开头的方法,例程中是指Running方法;
创建含主方法的测试类TestMain,在一种我们从ProxyFactoryBean中获得People实例对象,并一次调用该对象的方法,代码如下:
1 package aop.test; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.ClassPathXmlApplicationContext; 5 6 public class TestMain { 7 8 public static void main(String[] args) { 9 ApplicationContext ac = new ClassPathXmlApplicationContext( 10 "applicationContext.xml"); 11 12 //通过ProxyFactoryBean获取IComputer接口实现类的实例 13 People c = (People) ac.getBean("ProxyFactoryBean"); 14 c.speak(); 15 c.Running(); 16 c.Loving(); 17 c.died(); 18 } 19 } 20 该类运行结果如下:
图4.5 例程4.3运行结果
可以看到People类中的speak、Loving、died方法已经被拦截。但是Running方法却没有拦截,这是因为我们在JdkRegexpMethodPointcut中指定其excludedPattern属性把它排除在切入点之外的缘故。
|