javascript
Spring-AOP 基于Schema配置切面
- 概述
- 簡單切面配置實例
- 示例
- 配置命名切點
- 示例
- 各種增強類型的配置
- 示例
- 綁定連接點信息
- Advisor配置
概述
如果項目不能使用Java5.0, 那么就無法使用基于@AspectJ注解的切面。 但是Spring提供了基于Schema配置的方法,它完全可以替代基于@AspectJ注解聲明切面的方式。
基于@AspectJ注解的切面,本質上是將切點、增強類型的信息使用注解描述,我們將這兩個信息轉移到Schema的xml配置文件中,只是形式變了,本質還是相同的。
使用基于Schema的切面定義后,切點、增強類型的注解信息從切面類中剝離出來,原來的切面類也就蛻變為真正意義上的POJO了
簡單切面配置實例
代碼已托管到Github—> https://github.com/yangshangwei/SpringMaster
示例
首先來配置一個基于Schema的切面,它使用aop命名空間。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- (1)配置一個基于Schema的切面,它使用了aop命名空間, 因此首先聲明aop及指定aop文件 如上--><!-- ref引用adviceMethods,緊接著聲明切點表達式 以及增強方法使用adviceMethodsBean中的crossCutting方法--> <aop:config proxy-target-class="true"><aop:aspect ref="adviceMethods"><aop:before pointcut="target(com.xgj.aop.spring.advisor.schema.demo.BussinessOne) and execution(* program(..))" method="crossCutting"/></aop:aspect> </aop:config><!-- 配置bean,也可以通過使用context命名空間掃描注解的方式實例化 --> <bean id="bussinessOne" class="com.xgj.aop.spring.advisor.schema.demo.BussinessOne"/> <bean id="bussinessTwo" class="com.xgj.aop.spring.advisor.schema.demo.BussinessTwo"/> <!-- 增強方法所在的Bean --> <bean id="adviceMethods" class="com.xgj.aop.spring.advisor.schema.demo.AdviceMethods"/></beans>解析:
使用一個<aop:aspect>元素標簽定義切面,其內部可以定義多個增強。
在<aop:config>元素中可以定義多個切面。
通過<aop:before>聲明了一個前置增強,并通過pointcut屬性定義切點表達式,切點表達式的語法和@AspectJ中所用的語法完全相同,由于&&在XML中使用不便,所以一般用and操作符代替。
通過method屬性指定增強的方法,該方法應該是adviceMethods Bean中的方法。
AdviceMethods是增強方法所在的類,它是一個普通的java類,沒有任何特殊的地方,如下
package com.xgj.aop.spring.advisor.schema.demo;/*** * * @ClassName: AdviceMethods* * @Description: 增強方法所在的Bean* * @author: Mr.Yang* * @date: 2017年9月13日 下午4:38:25*/public class AdviceMethods {/*** * * @Title: crossCutting* * @Description: 改方法通過配置被用作增強方法* * * @return: void*/public void crossCutting() {System.out.println("crossCutting executed");} }業務類
package com.xgj.aop.spring.advisor.schema.demo;/*** * * @ClassName: BussinessOne* * @Description: 普通POJO* * @author: Mr.Yang* * @date: 2017年9月13日 下午4:37:56*/public class BussinessOne {public void program() {System.out.println("BussinessOne program executed");}public void fixBug() {System.out.println("BussinessOne fixBug executed");} } package com.xgj.aop.spring.advisor.schema.demo;/*** * * @ClassName: BussinessTwo* * @Description: 普通POJO* * @author: Mr.Yang* * @date: 2017年9月13日 下午4:38:10*/public class BussinessTwo {public void program() {System.out.println("BussinessOne program executed");}public void fixBug() {System.out.println("BussinessOne fixBug executed");} }測試類
package com.xgj.aop.spring.advisor.schema.demo;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class ConfigBySchemaTest {@Testpublic void test() {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/schema/demo/conf-bySchema.xml");BussinessOne bussinessOne = ctx.getBean("bussinessOne",BussinessOne.class);BussinessTwo bussinessTwo = ctx.getBean("bussinessTwo",BussinessTwo.class);// 根據配置文件中的切點表達式// target(com.xgj.aop.spring.advisor.schema.demo.BussinessOne)and// execution(* program(..)) ,只有// bussinessOne.program()符合條件bussinessOne.program();bussinessOne.fixBug();bussinessTwo.program();bussinessTwo.fixBug();}}運行結果
2017-09-15 22:01:42,550 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@61ee30d2: startup date [Fri Sep 15 22:01:42 BOT 2017]; root of context hierarchy 2017-09-15 22:01:42,704 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/schema/demo/conf-bySchema.xml] crossCutting executed BussinessOne program executed BussinessOne fixBug executed BussinessOne program executed BussinessOne fixBug executed可見,切面被正確的實施到目標Bean中。
配置命名切點
上面的例子中通過pointcut屬性聲明的切點時匿名切點,它不能被其他增強或其他切面引用。Spring提供了命名切點的配置方式。
示例
<aop:config proxy-target-class="true"><!-- (1) ---><aop:pointcut id="bussinessOneProgram" expression="target(com.xgj.aop.spring.advisor.schema.namePointcut.BussinessOne) and execution(* program(..))" /><aop:aspect ref="adviceMethods"><!-- (2) ---><aop:before pointcut-ref="bussinessOneProgram" method="crossCutting"/></aop:aspect> </aop:config>- 在(1)處使用<aop:pointcut>定義了一個切點,并通過id屬性進行命名.
- 在(2)通過pointcut-ref引用這個命名的切點。和<aop:before>一樣,除了引介增強外,其他任意增強類型都擁有pointcut、pointcut-ref和method這3個屬性。
當然了,<aop:pointcut>如果位于<aop:aspect>元素中,則該命名切點只能被當前<aop:aspect>內定義的元素訪問到。 為了能讓整個<aop:config>元素中定義的所有增強訪問,必須在<aop:config>元素下定義切點,如上所示。
如果有在<aop:config>元素下直接定義<aop:pointcut>,則必須保證 <aop:pointcut>在<aop:aspect>之前定義。 在 <aop:config>元素下還可以定義 <aop:advisor>,三者的順序要求為:首先是<aop:pointcut>,然后是 <aop:advisor>,最后是<aop:aspect>
各種增強類型的配置
基于Schema定義的切面和基于@AspectJ定義的切面內容基本一致,只是在表現形式上存在差異罷了。
下面通過實例來演示
示例
業務類
package com.xgj.aop.spring.advisor.schema.advices;public class BussinessSvc {public void dealBussinessBefore() {System.out.println("dealBussinessBefore executed");}public int dealWorkNumberForAfterReturring() {System.out.println("dealWorkNumberForAfterReturring executed");return 10;}public void dealWorkForAround(String workName) {System.out.println("dealWorkForAround executed");}public void dealBussinessForAfterThorowing(String bussinessName) {System.out.println("dealBussinessForAfterThorowing executed");// just a demo code ,in fact it's not cautiousif (bussinessName != null && "bug".equals(bussinessName))throw new IllegalArgumentException("iae Exception");elsethrow new RuntimeException("re Exception");}public void dealWorkForAfter() {System.out.println("dealWorkForAfter executed");} }切面增強邏輯
package com.xgj.aop.spring.advisor.schema.advices;import org.aspectj.lang.ProceedingJoinPoint;public class AdviceMethods {/*** * * @Title: before* * @Description: 前置增強對應的方法* * @param name* * @return: void*/public void beforeMethod() {System.out.println("--Before CrossCuttingCode--");}/*** * * @Title: afterReturning* * @Description: 后置增強對應方法 ,配置文件中的returing屬性必須和增強方法的入參名稱一致* * @param retVal* * @return: void*/public void afterReturningMethod(int retVal) {System.out.println("----afterReturning() begin----");System.out.println("returnValue:" + retVal);System.out.println("----afterReturning() end----");}/*** * * @Title: aroundMethod* * @Description: 環繞增強對應方法* * @param pjp* * @return: void* @throws Throwable*/public void aroundMethod(ProceedingJoinPoint pjp) throws Throwable {System.out.println("----aroundMethod() begin----");System.out.println("args[0]:" + pjp.getArgs()[0]);// 執行目標類的目標方法pjp.proceed();System.out.println("----aroundMethod() end----");}/*** * * @Title: afterThrowingMethod* * @Description: 拋出異常增強* * @param iae* * @return: void*/public void afterThrowingMethod(IllegalArgumentException iae) {System.out.println("----afterThrowingMethod()----");System.out.println("exception msg:" + iae.getMessage());System.out.println("----afterThrowingMethod()----");}/*** * * @Title: afterMethod* * @Description: final增強* * * @return: void*/public void afterMethod() {System.out.println("----afterMethod()----");} }為了演示引介增強引入的幾個接口和實現類
package com.xgj.aop.spring.advisor.schema.advices;/*** * * @ClassName: InterfaceOne* * @Description: 演示引介增強用* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:14:18*/ public interface InterfaceOne {void dealAnotherWork(); } package com.xgj.aop.spring.advisor.schema.advices;/*** * * @ClassName: InterfaceOneImpl* * @Description: 演示引介增強用* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:14:33*/ public class InterfaceOneImpl implements InterfaceOne {@Overridepublic void dealAnotherWork() {System.out.println("InterfaceOneImpl dealAnotherWork executed ");}} package com.xgj.aop.spring.advisor.schema.advices;/*** * * @ClassName: IntfBussiness* * @Description: 演示引介增強用* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:14:41*/ public interface IntfBussiness {void fixBug(); } package com.xgj.aop.spring.advisor.schema.advices;/*** * * @ClassName: IntfBussinessImpl* * @Description: 演示引介增強用* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:14:49*/ public class IntfBussinessImpl implements IntfBussiness {@Overridepublic void fixBug() {System.out.println("IntfBussinessImpl fixBug executed");}}配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><aop:config proxy-target-class="true"><!-- 前置增強命名切點 --><aop:pointcut expression="execution(* dealBussinessBefore(..))" id="before" /><!-- 后置增強命名切點 --><aop:pointcut expression="execution(* dealWorkNumberForAfterReturring(..))" id="afterReturnning" /><!-- 環繞增強命名切點 --><aop:pointcut expression="execution(* dealWorkForAround(..)) and within(com.xgj.aop.spring.advisor.schema.advices.BussinessSvc)" id="around" /><!-- 異常拋出命名切點 --><aop:pointcut expression="within(com.xgj.aop.spring.advisor.schema.advices.BussinessSvc) and execution(* dealBussinessForAfterThorowing(..))" id="afterThrowing"/><!-- final拋出命名切點 --><aop:pointcut expression="execution(* dealWorkForAfter(..))" id="after"/><!-- 引介增強不同,另述 --><aop:aspect ref="adviceMethods"><!-- 前置增強 --><aop:before pointcut-ref="before" method="beforeMethod" /><!-- 后置增強 --><aop:after-returning pointcut-ref="afterReturnning"method="afterReturningMethod" returning="retVal" /><!-- 環繞增強 --><aop:around pointcut-ref="around" method="aroundMethod"/><!-- 異常拋出增強 --><aop:after-throwing pointcut-ref="afterThrowing" method="afterThrowingMethod" throwing="iae"/><!-- final增強 --><aop:after pointcut-ref="after" method="afterMethod"/><!-- 引介增強 types-matching哪些類需要引介接口的實現 implement-interface要引介實現的接口 default-impl 引介默認的實現類--><aop:declare-parents types-matching="com.xgj.aop.spring.advisor.schema.advices.IntfBussiness+" implement-interface="com.xgj.aop.spring.advisor.schema.advices.InterfaceOne"default-impl="com.xgj.aop.spring.advisor.schema.advices.InterfaceOneImpl"/></aop:aspect></aop:config><!-- 業務類 --><bean id="bussinessSvc" class="com.xgj.aop.spring.advisor.schema.advices.BussinessSvc" /><bean id="intfBussinessImpl" class="com.xgj.aop.spring.advisor.schema.advices.IntfBussinessImpl"></bean><!-- 增強類 --><bean id="adviceMethods" class="com.xgj.aop.spring.advisor.schema.advices.AdviceMethods" /> </beans>測試類
package com.xgj.aop.spring.advisor.schema.advices;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class DifferentAdviceTest {@Testpublic void test() {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/schema/advices/conf-advices.xml");BussinessSvc bussinessSvc = ctx.getBean("bussinessSvc",BussinessSvc.class);// 方法執行前織入前置增強bussinessSvc.dealBussinessBefore();// 方法執行后織入后置增強bussinessSvc.dealWorkNumberForAfterReturring();// 方法執行時織入環繞增強bussinessSvc.dealWorkForAround("fixBug");// 方法執行時出現特定異常時織入異常拋出增強bussinessSvc.dealWorkForAfter();// 方法執行后,不管異常與否都執行的增強bussinessSvc.dealWorkForAfter();// 引介 --強制類型轉換成功,說明也實現了另外的接口IntfBussinessImpl intfBussinessImpl = ctx.getBean("intfBussinessImpl",IntfBussinessImpl.class);((InterfaceOne) intfBussinessImpl).dealAnotherWork();} }運行結果
2017-09-15 22:37:49,383 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@c24cb3: startup date [Fri Sep 15 22:37:49 BOT 2017]; root of context hierarchy 2017-09-15 22:37:49,485 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/schema/advices/conf-advices.xml] --Before CrossCuttingCode-- dealBussinessBefore executed dealWorkNumberForAfterReturring executed ----afterReturning() begin---- returnValue:10 ----afterReturning() end---- ----aroundMethod() begin---- args[0]:fixBug dealWorkForAround executed ----aroundMethod() end---- dealWorkForAfter executed ----afterMethod()---- dealWorkForAfter executed ----afterMethod()---- InterfaceOneImpl dealAnotherWork executed重點說一下引介增強 : 通過<aop:declare-parent>配置引介增強, 引介增強和其他類型的增強有所不同,它沒有method、pointcut和point-ref屬性
引介增強通過types-matching以及AspectJ切點表達式語法指定哪些bean需要引介接口的實現, implement-interface要引介實現的接口 , default-impl 引介默認的實現類
值的注意的是,雖然<aop:declare-parent>么有method屬性指定增強方法所在的Bean,但是<aop:aspect ref="adviceMethods">中的ref屬性依然要指定一個增強Bean。
綁定連接點信息
基于Schema配置的增強方法綁定連接點信息和基于@AspectJ綁定連接點信息所使用的方式沒有區別。
1)所有增強類型對應的方法第一個入參都可以聲明為JoinPoint(環繞增強可聲明為ProceedingJoinPoint)訪問連接點信息;
2)<aop:after-returning>(后置增強)可以通過returning屬性綁定連接點方法的返回值,<aop:after-throwing>(拋出異常增強)可以通過throwing屬性綁定連接點方法所拋出的異常;
3)所有增強類型都可以通過可綁定參數的切點函數綁定連接點方法的入參。
前兩種已經闡述過了,下面我們來看第三種綁定參數的方法
業務類
package com.xgj.aop.spring.advisor.schema.bindParameter;import org.springframework.stereotype.Component;/*** * * @ClassName: BussinessBindParam* * @Description: 使用注解定義的Bean* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:25:23*/@Component public class BussinessBindParam {public void program(String name, int number) {System.out.println("BussinessBindParam program execute");System.out.println("program:" + name + ", number:" + number);}public void fixbug(String name, int number, double salary) {System.out.println("BussinessBindParam fixBug executed");System.out.println("program:" + name + ", number:" + number + ",salary"+ salary);} }增強切面
package com.xgj.aop.spring.advisor.schema.bindParameter;import org.springframework.stereotype.Component;/*** * * @ClassName: AdviceMethodsBindParam* * @Description: 使用注解定義的Bean,同時也是切面類* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:25:13*/@Component public class AdviceMethodsBindParam {/*** * * @Title: crossCutting* * @Description: 改方法通過配置被用作增強方法* * * @return: void*/public void crossCutting(String name, int num) {System.out.println("----bindJoinPointParams()----");System.out.println("name:" + name);System.out.println("number:" + num);System.out.println("----bindJoinPointParams()----");} }配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- (1)配置一個基于Schema的切面,它使用了aop命名空間, 因此首先聲明aop及指定aop文件 如上--><!-- ref引用adviceMethods,緊接著引用命名切點 以及增強方法使用adviceMethodsBean中的crossCutting方法--> <aop:config proxy-target-class="true"><!-- 定義切點 --><aop:pointcut id="bussinessBindParamProgram" expression="target(com.xgj.aop.spring.advisor.schema.bindParameter.BussinessBindParam) and args(name,num,..)" /><aop:aspect ref="adviceMethodsBindParam"><aop:before pointcut-ref="bussinessBindParamProgram" method="crossCutting"/></aop:aspect> </aop:config><!-- 掃描類包以及使用注解定義的bean --> <context:component-scan base-package="com.xgj.aop.spring.advisor.schema.bindParameter"/> </beans>切點表達式通過 args(name,num,..) 綁定了連接點的兩個參數,對應增強類中的入參crossCutting(String name, int num) . 這兩個地方聲明的參數名必須相同
測試類
package com.xgj.aop.spring.advisor.schema.bindParameter;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class AdviceMethodsBindParamTest {@Testpublic void test() {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/schema/bindParameter/conf-bindParam.xml");BussinessBindParam bussinessBindParam = ctx.getBean("bussinessBindParam", BussinessBindParam.class);// args(name,num,..) 因此會匹配到bussinessBindParam.program("Spring", 8);// args(name,num,..) 因此會匹配到bussinessBindParam.fixbug("Spring4", 10, 20000);} }運行結果
2017-09-15 22:47:49,244 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6ac604: startup date [Fri Sep 15 22:47:49 BOT 2017]; root of context hierarchy 2017-09-15 22:47:49,350 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/schema/bindParameter/conf-bindParam.xml] ----bindJoinPointParams()---- name:Spring number:8 ----bindJoinPointParams()---- BussinessBindParam program execute program:Spring, number:8 ----bindJoinPointParams()---- name:Spring4 number:10 ----bindJoinPointParams()---- BussinessBindParam fixBug executed program:Spring4, number:10,salary20000.0Advisor配置
Advisor是Spring中切面概念的對應物,是切點和增強的復合體,不過僅包含一個切點和一個增強。在AspectJ中沒有對應的等價物,在aop Schema配置樣式中,可以通過配置一個Advisor。通過advice-ref屬性引用基于接口定義的增強,通過pointcut定義切點表達式,或者通過pointcut-ref引用一個命名的切點。
接口 及實現類
package com.xgj.aop.spring.advisor.schema.advisor;public interface Waiter {void greetTo(String name);void serverTo(String name); } package com.xgj.aop.spring.advisor.schema.advisor;import org.springframework.stereotype.Component;@Component public class NaiveWaiter implements Waiter {@Overridepublic void greetTo(String name) {System.out.println("greetTo " + name + "\n");}@Overridepublic void serverTo(String name) {System.out.println("serverTo " + name);}}前置增強
package com.xgj.aop.spring.advisor.schema.advisor;import java.lang.reflect.Method;import org.springframework.aop.MethodBeforeAdvice;/*** * * @ClassName: GreetingBeforeAdvice* * @Description: 前置增強* * @author: Mr.Yang* * @date: 2017年9月13日 下午8:55:12*/public class GreetingBeforeAdvice implements MethodBeforeAdvice {/*** 前置增強方法 當該方法發生異常時,將阻止目標方法的執行* * @param method* 目標類方法* @param objects* 目標類方法入參* @param target* 目標類對象實例* @throws Throwable*/@Overridepublic void before(Method method, Object[] args, Object target)throws Throwable {String clientName = (String) args[0];System.out.println("How are you " + clientName + " ?");} }配置文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:aop="http://www.springframework.org/schema/aop"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!-- (1)配置一個基于Schema的切面,它使用了aop命名空間, 因此首先聲明aop及指定aop文件 如上--><!-- ref引用adviceMethods,緊接著引用命名切點 以及增強方法使用adviceMethodsBean中的crossCutting方法--> <aop:config proxy-target-class="true"><!-- 命名切點 --><aop:pointcut expression="execution(* com..*.Waiter.greetTo(..))" id="beforeAdvice"/><aop:advisor advice-ref="greetingBeforeAdvice" pointcut-ref="beforeAdvice"/></aop:config><!-- 掃描類包以及使用注解定義的bean --> <context:component-scan base-package="com.xgj.aop.spring.advisor.schema.advisor"/> <!-- advice --> <bean id="greetingBeforeAdvice" class="com.xgj.aop.spring.advisor.schema.advisor.GreetingBeforeAdvice"/> </beans>測試類
package com.xgj.aop.spring.advisor.schema.advisor;import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class AdvisorTest {@Testpublic void test() {ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:com/xgj/aop/spring/advisor/schema/advisor/conf-advisor.xml");NaiveWaiter naiveWaiter = ctx.getBean("naiveWaiter", NaiveWaiter.class);naiveWaiter.greetTo("XiaoGongJiang");naiveWaiter.serverTo("XiaoGongJiang");} }運行結果
2017-09-15 23:47:57,497 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@61ee30d2: startup date [Fri Sep 15 23:47:57 BOT 2017]; root of context hierarchy 2017-09-15 23:47:57,599 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/schema/advisor/conf-advisor.xml] How are you XiaoGongJiang ? greetTo XiaoGongJiangserverTo XiaoGongJiang總結
以上是生活随笔為你收集整理的Spring-AOP 基于Schema配置切面的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring-AOP @AspectJ进
- 下一篇: Spring JDBC-Spring对D