javascript
Spring-AOP 流程切面
- 概述
- 實例
- 總結
概述
Spring的流程切面由DefaultPointcutAdvisor和ControlFlowPointcut實現。 流程切點代表由某個方法直接或者間接發起調用的其他方法。
實例
代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster
package com.xgj.aop.spring.advisor.ControlFlowAdvisor;public class Waiter {public void greetTo(String name) {System.out.println("Waiter Greet To " + name);}public void serverTo(String name) {System.out.println("Waiter Server To " + name);} }我們通過一個WaiterDelegate類調用Waiter中的所有方法
package com.xgj.aop.spring.advisor.ControlFlowAdvisor;public class WaiterDelegate {private Waiter waiter;public void setWaiter(Waiter waiter) {this.waiter = waiter;}/*** * * @Title: service* * @Description: waiter類中方法的調用,通過該方法發起* * @param name* * @return: void*/public void service(String name) {waiter.greetTo(name);waiter.serverTo(name);}}我們希望所有由WaiterDelegate .service方法發起調用的其他方法都織入GreetingBeforeAdvice前置增強,就必須使用流程切面來完成了。
編寫增強
package com.xgj.aop.spring.advisor.ControlFlowAdvisor;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;public class GreetingBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] args, Object target)throws Throwable {// 輸出切點System.out.println("Pointcut:" + target.getClass().getName() + "."+ method.getName());String clientName = (String) args[0];System.out.println("How are you " + clientName + " ?");}}下面使用DefaultPointcutAdvisor配置一個流程切面來完成這一需求
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:p="http://www.springframework.org/schema/p"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 目標類 --><bean id="waiterTarget" class="com.xgj.aop.spring.advisor.ControlFlowAdvisor.Waiter"/><!-- 增強 --><bean id="greetingBeforeAdvice" class="com.xgj.aop.spring.advisor.ControlFlowAdvisor.GreetingBeforeAdvice"/><!-- 流程切點 指定流程切點的類 和 流程切點的方法--><bean id="controlFlowPointcut" class="org.springframework.aop.support.ControlFlowPointcut"><constructor-arg type="java.lang.Class" value="com.xgj.aop.spring.advisor.ControlFlowAdvisor.WaiterDelegate"/><constructor-arg type="java.lang.String" value="service"/> </bean><!-- 切面 --><bean id="controlFlowAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"p:pointcut-ref="controlFlowPointcut"p:advice-ref="greetingBeforeAdvice"/><!-- 代理類 --><bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"p:interceptorNames="controlFlowAdvisor"p:target-ref="waiterTarget"p:proxyTargetClass="true"/></beans>我們來看下ControlFlowPointcut
兩個構造函數:
ControlFlowPointcut(Class<?> clazz) 指定一個類作為流程切點
ControlFlowPointcut(Class<?> clazz, String methodName) 指定一個類和某一個方法作為流程切點
我們這里指定com.xgj.aop.spring.advisor.ControlFlowAdvisor.WaiterDelegate中的service()方法作為流程切點,表示所有通過該方法直接或者間接發起的調用匹配切點。
編寫測試類
package com.xgj.aop.spring.advisor.ControlFlowAdvisor;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class ControlFlowAdvisorTest {@Testpublic void test() {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/ControlFlowAdvisor/conf-controlFlowAdvisor.xml");Waiter waiter = ctx.getBean("waiter", Waiter.class);waiter.greetTo("XiaoGongJiang");waiter.serverTo("XiaoGongJiang");System.out.println("\n");WaiterDelegate waiterDelegate = new WaiterDelegate();waiterDelegate.setWaiter(waiter);waiterDelegate.service("XiaoGongJiang");} }運行結果:
2017-08-20 03:36:49,907 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@76566fb: startup date [Sun Aug 20 03:36:49 BOT 2017]; root of context hierarchy 2017-08-20 03:36:50,020 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/ControlFlowAdvisor/conf-controlFlowAdvisor.xml] Waiter Greet To XiaoGongJiang Waiter Server To XiaoGongJiangPointcut:com.xgj.aop.spring.advisor.ControlFlowAdvisor.Waiter.greetTo How are you XiaoGongJiang ? Waiter Greet To XiaoGongJiang Pointcut:com.xgj.aop.spring.advisor.ControlFlowAdvisor.Waiter.serverTo How are you XiaoGongJiang ? Waiter Server To XiaoGongJiang我們在測試類中直接調用了greetTo和serverTo,此時增強并沒有起作用,
我們通過WaiterDelegate的service調用Waiter中的greetTo和serverTo,,可以看到Waiter的兩個方法都織入了增強
總結
流程切面和動態切面從某種城都說說可以算是一類切面,因為二者都需要在運行期判斷動態的環境。 對于流程切面來講,代理對象那個在每次調用目標類方法時,都需要判斷方法調用堆棧中是否有滿足流程切點要求的方法,和動態切面一樣,對性能的影響很大.
總結
以上是生活随笔為你收集整理的Spring-AOP 流程切面的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring-AOP 动态切面
- 下一篇: Spring-AOP 引介切面