spring aop的使用分为两种,一种是使用注解来实现,一种是使用配置文件来实现。
先来简单的介绍一下这两种方法的实现,接下来详细的介绍各处的知识点便于查阅。目录如下:
1.基于注解实现spring aop
2.基于配置文件实现spring aop
3.增强的分类
4.切点表达式的构成
1.基于注解来实现的方法
基于注解并不意味着不需要配置文件,只不过是在配置文件中所需要的配置很少。切面编程,显然我们需要一个增强类,一个被增强的普通类。
配置文件中需要添加以下的内容
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation= "http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd" <!--引入配置--> <context:component-scan base-package="com.test.aspect"/> <!--扫描这两个包-->
<context:component-scan base-package="com.test.user"/>
<aop:aspectj-autoproxy/> <!--开启aop自动扫描-->
下面是增强类
package com.test.aspect;
@Component
@Aspect public class TestAspect{
@Before("execution(* com.test.user.Login.greetTo(..))") public void beforeDoing(){ //do somthing } }
下面是被增强类
@Component
public Class Login{ public void greetTo(){ //some action } }
这样就可以完成对被增强类的增强。
2.基于配置文件的方式
非注解方式的首先把上面的注解都去掉,主要内容在配置文件中,配置文件如下 (其实还有 <aop:advisor>的配置,不过是旧版本所用,如果spring版本较低使用)
xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation= "http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd" <!--引入配置--> <aop:config proxy-target-class="true"> <!--aop config 是最外层的内容--> <aop:pointcut id="pc" expression="execution(* com.test.aspect.*(..))"/> <!--首先定义了切入点--> <aop:aspect ref="TestAspect" order="2"> <!--定义了增强类 order指的是增强织入的顺序--> <aop:before method="beforeDoing" pointcut-ref="pc"/> <!--指定增强类中一个方法为before增强,切入点为之前定义的切入点--> </aop:aspect> </aop:config>
3.增强的分类
增强主要有以下几种:1.before 2.after 3.after-returning 4.after-throwing 5.around
依次进行一下介绍,提供注解方式和配置文件方式
// before 增强是在所需要增强的方法执行之前被织入 @before("execution(* org.test.*.*(..))") public void beforeAction(JoinPoint jp) //如果要使用joinpoint必须是第一个参数 { jp.getSignature().getName(); //获得目标方法 jp.getArgs(); //获得目标方法的参数 //dosomething } 在配置文件中写成 <aop:before pointcut="execution(* org.test.*.*(..))" method="beforeAction"/>
//after 增强无论目标方法如何结束,都会织入在方法的后面 @After("execution(* org.test.*.*(..))") public void afterAction(JoinPoint jp){ //doSomething() } <aop :after pointcut="execution(* org.test.*.*(..))" method="afterAction">
//AfterReturning 将在目标方法正常完成后被织入 @AfterReturning(returning ="rvt" ,pointcut="execution(* org.test.*.*(..))") public void log(JointPoint jp,Object rvt){ //rvt是目标方法的返回值 } <aop:after-returning pointcut="execution(* org.test.*.*(..))" method="log"/>
//afterthrowing 用于处理程序中未被处理的异常 @AfterThrowing(throwing="ex",pointcut="execution(* org.test.*.*(..))") public void recovery(Throwable ex){ //ex 是目标方法抛出的异常 } <aop:after-throwing pointcut="execution(* org.test.*.*(..))" method="recovery" throwing="ex">
//round 功能比较强大,可以环绕被增强方法 @Around("execution(* org.test.*.*(..))") public Object round(ProceedingJoinPoint pjp){ Object[] args=jp.getArgs(); //获得参数 Object rvt=jp.procceed(args);//调用目标方法,可以将修改后的参数传入 return rvt+1; //可以对返回值进行处理 } <aop:around pointcut="execution(* org.test.*.*(..))" method="round"/>
4.切点表达式的构成
//可以定义一个切点,然后后续重复使用,比较方便 @Pointcut("execution(* org.test.*.*(..))") public void myPointcut(){} @Before(pointcut="myPointcut") public void before(){ .... }
//下面是配置文件方法中的对应内容 <aop:poincut id="myPointcut" expression=""execution(* org.test.*.*(..))""/>
<aop:aspect ref="TestAspect">
<aop:before method="before" pointcut-ref="myPointcut"/>
</aop:aspect>
之前所用的切点指示符只有 execution 还有 within this target args 下面依次进行介绍
execution(1? 2 3? 4(5) 6?) 1.指定方法的修饰符 public private等,该部分可省略 2.指定方法的返回值 该部分不可省略 不过一般用*代表任意返回值 3.指定方法所属的类 可以省略,可用通配符 4.指定方法名,可用通配符,不可省略 5.指定方法的参数支持*与.. ()表示没有参数 (*)表示一个任意类型的参数 (..)表示任意数量的参数 (String,..)表示有一个String 参数,后面可以有任意个参数不可省略 6.指定方法声明要抛出的异常(throws) 可用通配符 可省略 eg. execution(* org.test.service.impl.*.*(..))//org.test.service.imple 包下所有类的所有方法
pointcut="execution(* org.test.service.impl.*.*(..))"
//args 表示入参的类型 当入参类型匹配时织入 强调参数,可用execution代替 arg(Integer) //within 类匹配模式 within(org.test.User) //匹配User中的所有类,最小粒度,不能到方法 within(org.test.*) //匹配org.test包中的所有类 within(org.test..*) //匹配org.test包及子孙包中的所有类 //target和within类似,匹配符合的类别 //this判断代理对象的类是否匹配 //这几种都没怎么用过,所以简略提一下,用到后再补充
切点表达式也可以用复合的方式 && || !
用法很简单,而且个人感觉用处并不大...
@Before("A&&B") AB均为之前描述的表达式
如果在xml中配置则要用and or等 pointcut="A and B"
先写到这里,如果有需要补充的再来!