我们来分析一下上节课的application.xml里面代码的写法
原写法:
<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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置目标对象,我们会在src/test/java/com.huanf.test/AopTest类里面进行测试target-->
<bean id="target" class="com.huanf.aop.Target"></bean>
<!--配置切面对象-->
<bean id="myAspecT" class="com.huanf.aop.MyAspect"></bean>
<!--配置织入,内部要配置: 哪些方法(其实指的就是切点)需要进行哪些增强(其实指定就是前置增强、后置增强、其它增强)-->
<aop:config>
<!--声明切面,即指定上面的id作为切面,不然上面我们写的id="myAspecT"只是一个普通的bean,当声明了之后myAspecT就不再是普通的bean,而是切面-->
<aop:aspect ref="myAspecT">
<!--切面=切点+通知,通知也称为增强。before表示前置增强,method表示哪个方法(在MyAspect类里面的哪个方法)要进行前置增强。
pointcut表示切点,execution里面表示对Target类的save方法增强。下面那行的execution括号里面的叫'切点表达式'-->
<aop:before method="before_met" pointcut="execution(public void com.huanf.aop.Target.save())"/>
<!--上面那行的意思: 当访问save方法时,save方法会进行前置增强,前置增强的代码在MyAspect类的before_met方法里面-->
</aop:aspect>
</aop:config>
<!--把上面那个<aop:config>标签注释掉,那么我们在com.huanf.test.AopTest类里面测试的就是未增强的save方法-->
<!--如果要增强别的方法的话,就把execution括号里面的全限定名改掉即可-->
</beans>
首先分析aop:config标签里面的写法:
1、aop:config: aop的配置
2、<aop:aspect ref="xxx">: 声明切面,ref指定某个类里面的切面
3、<aop:kkk method="xxx" pointcut="execution(yyy)"/>:kkk表示是前置增强还是后置增强,yyy方法(切点方法)+xxx方法(增强方法)=切面,pointcut里面的 是切点表达式(通过一个表达式可以指定多个切点方法)
这节课主要讲pointcut切点表达式,接下来会着重学习 '切点表达式怎么写'
表达式语法:
execution([修饰符] 表达值类型 包名.类名.方法名(参数))
1、修饰符可以省略,一般我们写的时候都是习惯省略
2、返回值类型、包名、类名、方法名可以使用*代表任意
3、包名与类名之间一个点.代表当前包下的类,两个点..代表当前包及其子包下的类
4、如果有多个参数,可以使用..代表,任意参数个数
例如如下,下面所说的'方法'指的是'被增强的方法':
表达式 | 作用 |
---|---|
execution(public void com.huanf.aop.Target.method()) | 表示必须是com.huanf.aop包下的Target类的method方法,并method方法没有返回值 |
execution(void com.huanf.aop.Target.*(..)) | 表示必须是com.huanf.aop包下的Target类,方法可以是Target类里面的全部方法,这些方法如果没有返回 |
execution(* com.huanf.aop..(..)) | 常用写法,表示com.huanf.aop包下的全部类的全部方法(方法可以是任意返回值)都能被增强 |
execution(* com.huanf.aop...(..)) | 表示com.huanf.aop包及其子包下的全部类的全部方法(方法可以是任意返回值)都能被增强 |
execution(* ...*(..)) | 没意义,不要这样写 |
具体操作:
去applicationContext.xml里面把切点表达式修改为如下
<aop:before method="before_met" pointcut="execution(* com.huanf.aop.*.*(..))"/>
pointcut: 切点表达式
根据上面的分析,当我们已经配置了多个<aop:xxx method="yyy" pointcut="execution(* com.huanf.aop..(..))"/>,也就是配置了多个增强(也叫通知),如果这多个增强的 切点表达式相同,也就是相同的pointcut="execution(* com.huanf.aop..(..))",那我们就可以把切点表达式抽取出来
当多个增强的切点表达式相同时,可以将切点表达式进行抽取,在增强中使用pointcut-ref属性代替pointcut属性来引用抽取后的切点表达式
具体操作:
第一步: 把applicationContext.xml里面的aop:config标签改为如下
xxxxxxxxxx
<aop:config>
<aop:aspect ref="myAspecT">
<aop:pointcut id="zidingyi_chouqu" expression="execution(* com.huanf.aop.*.*(..))"/>
<aop:around method="around_met" pointcut-ref="zidingyi_chouqu"/>
<aop:after-throwing method="afterThrowing_met" pointcut-ref="zidingyi_chouqu"/>
<aop:after method="after_met" pointcut-ref="zidingyi_chouqu"/>
</aop:aspect>
</aop:config>
第二步: 在AopTest类进行运行测试