如果有这样的需求:我们对一个方法进行切入通知,但只有这个方法在一个特定方法中被调用的时候执行通知,我们可以使用ControlFlowPointCut流程切入点
BeanOne.java
package ch7.ControlFlowPointCut;

public class BeanOne ...{
public void foo()...{
System.out.println("foo-one");
}
public void bar()...{
System.out.println("bar-one");
}
}
SimpleAdvise
package ch7.ControlFlowPointCut;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class SimpleAdvise implements MethodInterceptor ...{

public Object invoke(MethodInvocation invocation) throws Throwable ...{
System.out.println("before");
Object retVal=invocation.proceed();
System.out.println("after");
return retVal;
}
}
测试代码:
package ch7.ControlFlowPointCut;
import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.ControlFlowPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class Test ...{

/** *//**
* @param args
*/
public static void main(String[] args) ...{
BeanOne one=new BeanOne();
BeanOne proxyOne;
Pointcut pc=new ControlFlowPointcut(Test.class,"runfoo");
Advice advice=new SimpleAdvise();
Advisor advisor=new DefaultPointcutAdvisor(pc,advice);
//创建BeanOne代理
ProxyFactory pf1=new ProxyFactory();
pf1.addAdvisor(advisor);
pf1.setTarget(one);
proxyOne=(BeanOne)pf1.getProxy();
//直接调用foo
proxyOne.foo();
//通过runfoo方法调用foo
Test.runfoo(proxyOne);
}
public static void runfoo(BeanOne beanOne)...{
beanOne.foo();
}
}
测试结果:
foo-one
before
foo-one
after
可以看到直接执行foo没有进行切入,而通过runfoo方法执行foo就进行了切入
使用流程切入点可以解决不少问题,但值得注意的是,使用流程切入点在jdk1.4中比其他切入点要慢5倍,在1.3上则要慢10倍,追求高性能的要慎重使用
本文介绍了在Spring框架中如何使用ControlFlowPointCut进行流程控制切入点的实践。通过示例展示了当方法在特定上下文中被调用时,如何触发切入通知。测试结果显示,直接调用foo方法不会执行通知,而通过runfoo方法调用foo方法时会执行通知。虽然ControlFlowPointCut能解决特定场景的问题,但在JDK 1.4中性能下降5倍,1.3中下降10倍,因此在性能敏感的场景下需要谨慎使用。
1293

被折叠的 条评论
为什么被折叠?



