spring AOP编程
前提:
导入aop需要的jar:
aspectjweaver.jar和aspectjrt.jar和cglib-nodep-2.1_3.jar
加入aop需要的命名空间:
xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
spring提供了两种切面使用方式:
基于注解方式和基于xml方式。
基于注解方式进行AOP开发:
前提:
前面加上aop声明
打开@Aspect的支持:<aop:aspectj-autoproxy/>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <context:component-scan base-package="cn.itcast"/> <aop:aspectj-autoproxy/>
一些有关注解:
@Aspect 声明切面,作用在类上
@Pointcut 声明切入点
例子:
@Pointcut("execution (* cn.itcast.service.impl.PersonServiceBean.*(..))") private void anyMethod(){}//声明一个切入点,采用方法定义的形式
注意点:
1、切入点的声明和方法类似,但是切入点的名称为方法名+(),比如上面的切入点名为anyMethod()
2、切入点的扫描内容格式基本固定:execution(切入点表达式)
切入点表达式:
分解: 返回值类型 包名.类名.方法名(方法参数)
可用的符号:
* 通配符,表示任意
.. 两种意义,一个表示可变参,在参数列表中使用,一个表示:该包下的子包和该包,在package中使用
!非
切入点表达式例子:
返回值是String类型的:
execute(java.lang.String cn.itcast.service..*.*(..))
要求输入参数的第一个参数是String类型:
execute(* cn.itcast.service..*.*(java.lang.String,..))
要求返回值不是void:
execute(!void cn.itcast.service..*.*(..))
通知作用在方法上
@Before 前置通知
@Before("anyMethod()")
如果希望得到拦截到的切入点中的参数,可以这样:
@Before(value="anyMethod() && args(name)") public void doBefore(String name){//前置通知,里面的参数为切入点名 System.out.println("前置通知"+name); }
@AfterReturning 后置通知
@AfterReturning("anyMethod()")
如果希望在后置通知中得到方法的返回值:
@AfterReturning(pointcut="anyMethod()",returning="result") public void doAfterReturning(String result){ System.out.println("后置通知"+result); }
@After 最终通知
@After("anyMethod()") public void doAfter(){ S ystem.out.println("最终通知"); }
@AfterThrowing 例外通知
@AfterThrowing("anyMethod()")
如果希望例外通知中得到异常信息:
@AfterThrowing(pointcut="anyMethod()",throwing="e") public void doAfterThrowing(Exception e){ System.out.println("例外通知"+e); }
@Around 环绕通知
@Around("anyMethod()") public Object doBasicProfiling(ProceedingJoinPoint pjp)throws Throwable{ Object result=null; if(true){//判断用户是否有权限 System.out.println("进入方法"); result=pjp.proceed();//这个方法类似于doFilter System.out.println("退出方法"); } return result; }
注意:
1、环绕通知的作用方法的格式是不变的,只有方法名和参数名可变
2、环绕通知跟struts2中的拦截器很相似。ProceedingJoinPoint对象的proceed()方法和invocation.invoke()方法类似
基于xml形式进行AOP开发:
我们原来的切面变成了普通的java类:
package cn.itcast.service; import org.aspectj.lang.ProceedingJoinPoint; import org.springframework.stereotype.Component; @Component("aspectBean") public class MyInterceptor { public void doBefore(){//前置通知 System.out.println("前置通知"); } public void doAfterReturning(String result){ System.out.println("后置通知"+result); } public void doAfter(){ System.out.println("最终通知"); } public void doAfterThrowing(Exception e){ System.out.println("例外通知"+e); } public Object doBasicProfiling(ProceedingJoinPoint pjp)throws Throwable{ Object result=null; if(true){//判断用户是否有权限 System.out.println("进入方法"); result=pjp.proceed();//这个方法类似于doFilter System.out.println("退出方法"); } return result; } }
beans.xml的对应配置:
<aop:config> <aop:aspect id="asp" ref="aspectBean"> <aop:pointcut id="mycut" expression="execution(* cn.itcast.service.impl..*.*(..))"/> <aop:before method="doBefore" pointcut-ref="mycut"/> <aop:after-returning method="doAfterReturning" pointcut-ref="mycut" returning="result"/> <aop:after method="doAfter" pointcut-ref="mycut"/> <aop:after-throwing method="doAfterThrowing" pointcut-ref="mycut" throwing="e"/> <aop:around method="doBasicProfiling" pointcut-ref="mycut"/> </aop:aspect> </aop:config>
前置通知的参数获取使用xml配置的我没有弄出来,不转牛角尖了,知道的可以告诉下,谢谢!