表达式分析:
expression="execution(* cn.com.xinli.service.impl.PersionServiceBean.*(..))"
1.第一个星号表示 拦截方法的返回值为任意
如果为 java.lang.String 表示只拦截 返回值为String的方法
如果为 void 则表示只拦截 返回值为 void 的方法
如果为 !void 则表示只拦截 返回值 非 void的方法
2. 如果我们只拦截 方法第一个参数为String,剩下的参数类型任意 则可以
expression="execution(java.lang.String cn.com.xinli.service.impl.PersionServiceBean.*(java.lang.String,..))"
未处理的问题:
基于配置实现aop的方式 如何给各种通知传递参数,比如给前置通知传递方法的入参,给后置通知传递方法的返回值,等晚上发了版本在研究,基于注解的已经实现了.
处理遗留问题:基于注解的方式实现在前置置通知得到拦截方法的入参,在置通知得到拦截方法的返回值,谢谢楼下的 windywindy 帮助,表示感谢!!
首先在beans.xml中配置切面,拦截表达式,各种通知的定义。。。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"> <aop:aspectj-autoproxy proxy-target-class="true"/> <!--切面和业务bean都需要交给容器管理--> <bean id="myInterceptor" class="cn.com.xinli.service.MyInterceptor"></bean> <bean id="personService" class="cn.com.xinli.service.impl.PersionServiceBean"></bean> <aop:config> <!-- 定义一个切面 --> <aop:aspect id="asp" ref="myInterceptor"> <!-- 定义切入点,定义拦截表达式,前置通知,后置通知,等.. --> <aop:pointcut id="mycut" expression="execution(* cn.com.xinli.service.impl.PersionServiceBean.*(..))and args(name)"/> <aop:before pointcut-ref="mycut" method="doAccessCheck" arg-names="name"/> <aop:after-returning pointcut-ref="mycut" method="doAfterReturning" returning="result"/> <aop:after-throwing pointcut-ref="mycut" method="doAfterThrowing"/> <aop:after pointcut-ref="mycut" method="doAfter"/> <aop:around pointcut-ref="mycut" method="doBasicProfiling"/> </aop:aspect> </aop:config> </beans>
1.前置置通知得到拦截方法的入参,关键就是在前置方法中定义一个连接点,从连接点中得到入参,如果有多个则可以用便利的方式得到。 测试调用 ps.save("huxl");
public void doAccessCheck(JoinPoint joinPoint) { System.out.println("前置通知:"); Object[] args = joinPoint.getArgs(); for (int i=0; i<args.length; i++) { System.out.println("入参:"+args[i]); } }
结果:
入参:huxl进入方法我是save()方法后置通知中得到结果:null最终通知退出方法
2.在后置通知中得到拦截方法的返回值 关键在与给在配置文件中 给后置方法配置返回的参数,在后置方法中将返回参入当做入参传递 测试 ps.getPersonName(1);
public void doAfterReturning(String result) { System.out.println("后置通知中得到结果:"+result); }
结果:
前置通知:入参:1进入方法我是getPersonName()方法后置通知中得到结果:xxx最终通知退出方法
