spring aop配置及用例说明(4)
欢迎交流转载:http://www.cnblogs.com/shizhongtao/p/3476161.html
这里简单对xml的配置方式做一下描述.代码还是上一篇(http://www.cnblogs.com/shizhongtao/p/3473362.html)的代码,只是配置方式改为xml的配置方式.测试用例类包括NotVeryUsefulAspect和Maneger两个。代码我还是贴一下。
1 package com.bing.test; 2 3 public class Manager { 4 private String myName; 5 private String description; 6 7 public void sayHello() { 8 System.out.println("Hello " + myName); 9 } 10 11 public void getDes() { 12 System.out.println(description); 13 14 } 15 16 public String getName() { 17 System.out.println("执行getName"); 18 return myName; 19 } 20 21 public String throwTest() throws Exception { 22 if (true) { 23 24 throw new Exception("new throwing test!"); 25 } 26 return "fail"; 27 } 28 }
1 package com.bing.test; 2 3 4 public class NotVeryUsefulAspect { 5 //配置切入点集合,这样在下面可以直接引入 6 /* @Pointcut("execution(public * com.bing.test..*.sayHello(..))") 7 public void inManager() {} 8 @Pointcut("within(com.bing.test..*)") 9 public void excutionManager() {}*/ 10 // 表示在方法前面执行 11 public void before() { 12 13 System.out.println("before Method"); 14 } 15 public void afterReturning(Object retVal) { 16 if(retVal!=null) 17 System.out.println("参数是:"+retVal); 18 System.out.println("afterReturning Method"); 19 } 20 //@After("execution(public * com.bing.test..*.*(..))") 21 public void after() { 22 23 System.out.println("after Method"); 24 } 25 public void afterThrow(Exception ex){ 26 27 System.out.println(ex.getMessage()); 28 29 System.out.println("AfterThrowing Method!"); 30 } 31 }
下面我就对xml文件做一下说明。在第一篇中有一个简单的xml配置,如下
<bean id="myInterceptor" class="com.bing.test.NotVeryUsefulAspect"></bean> <aop:config> <aop:aspect id="myAspect" ref="myInterceptor"> <aop:before method="before" pointcut="execution(public * com.bing..*.sayHello(..))" /> <!-- 第一个*表示任何返回类型,“..”表示这个包下的所有子包,第二个*代表所有类,第二个“..”匹配了一个接受任意数量参数 --> <!-- 当然sayHello方法你也可以用*代替,这样就表示所有方法。 --> </aop:aspect> </aop:config>
上面的配置很清晰,不过也有点不够灵活。加入做大量配置的话,可能会写一些重复的xml代码。另外一种配置方式是:我们用 <aop:config>元素来申明一个切入点。如果你想对 所有service层来声明,你可以这样写:
1 <aop:config> 2 3 <aop:pointcut id="businessService" 4 expression="execution(* com.xyz.myapp.service.*.*(..))"/> 5 6 </aop:config>这个expression用的表达式和,前几篇介绍的表达式一样,这时候如果你想用定义的切面类,可以这样配置:
1 <aop:config> 2 3 <aop:aspect id="myAspect" ref="aBean"> 4 5 <aop:pointcut id="businessService" 6 expression="execution(* com.xyz.myapp.service.*.*(..)) && this(service)"/> 7 <aop:before pointcut-ref="businessService" method="monitor"/> 8 ... 9 10 </aop:aspect> 11 12 </aop:config>上面的配置说明在ref="aBean"所指向的类中有着么一个方法:
public void monitor(Object service) { ... }
综上,我对上一篇进行xml方式进行配置如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 6 xsi:schemaLocation="http://www.springframework.org/schema/beans 7 http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd 9 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd 10 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"> 11 12 <context:annotation-config /> 13 <aop:aspectj-autoproxy /> 14 15 <context:component-scan base-package="com.bing"> 16 <context:exclude-filter type="annotation" 17 expression="org.springframework.stereotype.Controller" /> 18 <context:exclude-filter type="regex" 19 expression="com\.bing\.vo.*" /> 20 <context:exclude-filter type="regex" 21 expression="com\.bing\.util.*" /> 22 </context:component-scan> 23 <!-- 自定义的配置文件 --> 24 <bean 25 class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 26 <property name="locations"> 27 <list> 28 <value>classpath:/user.properties</value> 29 </list> 30 </property> 31 <property name="fileEncoding" value="utf-8" /> 32 </bean> 33 <bean id="manager" class="com.bing.test.Manager"> 34 <property name="myName" value="${user.name}"></property> 35 <property name="description" value="${user.description}"></property> 36 </bean> 37 38 <bean id="myInterceptor" class="com.bing.test.NotVeryUsefulAspect"></bean> 39 40 <aop:config> 41 <!-- 匹配com.bing包以及子包下所有类以say开头的方法 --> 42 <aop:pointcut expression="execution(public * com.bing..*.say*(..))" 43 id="someMethod" /> 44 <!-- 匹配com.bing.test下的Manager类 --> 45 <aop:pointcut expression="execution(public * com.bing..*.get*(..))" 46 id="returnMethod" /> 47 <!-- 匹配com.bing.test下所有类 --> 48 <aop:pointcut expression="within(com.bing.test.*)" id="allMethod" /> 49 <!-- 配置切入点和建议 --> 50 <aop:aspect id="myAspect" ref="myInterceptor"> 51 <aop:before method="before" 52 pointcut-ref="someMethod" /> 53 <aop:after method="after" 54 pointcut-ref="someMethod" /> 55 </aop:aspect> 56 <!-- 带返回值的切入点配置 --> 57 <aop:aspect id="myAspect2" ref="myInterceptor"> 58 <aop:after-returning method="afterReturning" returning="retVal" 59 pointcut-ref="returnMethod" /> 60 </aop:aspect> 61 </aop:config> 62 63 </beans>
补充:xml方法配置Around参数得到方法的参数。例如对于某一个有两个参数的方法,我配置如下切入点
1 public Object profile(ProceedingJoinPoint call, String name, int age) throws Throwable { 2 StopWatch clock = new StopWatch( 3 "Profiling for '" + name + "' and '" + age + "'"); 4 try { 5 clock.start(call.toShortString()); 6 return call.proceed(); 7 } finally { 8 clock.stop(); 9 System.out.println(clock.prettyPrint()); 10 } 11 }
对应上面java代码的xml配置文件如下:
1 <aop:config> 2 <aop:aspect ref="profiler"> 3 4 <aop:pointcut id="theExecutionOfSomeFooServiceMethod" 5 expression="execution(* x.y.service.FooService.getFoo(String,int)) 6 and args(name, age)"/> 7 8 <aop:around pointcut-ref="theExecutionOfSomeFooServiceMethod" 9 method="profile"/> 10 11 </aop:aspect> 12 </aop:config>