基于xml文件的AOP配置
基于xml文件的aop配置
-
把通知类对象交割spring来管理,即配置通知类对象
<!-- 1、配置logger对象(这里是通知类) --> <bean id="logger" class="com.mypro.utils.logger"></bean>
-
使用aop:config标签表明开始aop的配置
<aop:config></aop:config>
-
在aop:config标签内部使用aop:aspect标签表明配置切面
-
id属性:是给切面提供一个唯一标识
-
ref属性:指定通知类的bean的id
<aop:config> <aop:aspect id="loggeradvice" ref="logger"></aop:aspect> </aop:config>
-
-
在aop:aspect标签的内部使用对应的标签来配置通知的类型
-
前置通知标签:aop:before
-
后置通知标签:aop:after-returning
-
异常通知标签:aop:after-throwing
-
最终通知标签:aop:after
-
上述通知标签共有的属性
-
method属性:用于指定通知类的方法
-
pointcut-ref属性:用于指定配置的切入点表达式的唯一标识的id
-
pointcut属性:用于指定切入点表达式,该表达式的含义是对业务层中的方法增强
-
切入点表达式的标准格式:execution(访问修饰符 返回值类型 包名.包名..类名.方法名(参数列表)) 只针对某一个方法
-
全通配符写法:
* *..*.*(..)
-
标准格式到全通配写法的演变
-
访问修饰符可以省略
-
返回值可以用通配符*代替,表示任意返回值 *
-
包名也可以用通配符代替,有几个包就有几个 * *
-
包名也可以简化:..表示当前包及所有子包 * *..
-
类名也可以用通配符*代替,表示任意类 * * *..*
-
方法名也可以用通配符代替,表示任意方法 * *..*.*
-
参数列表
-
可以是基本数据类型 示例 int
-
可以是引用类型写包名.类名的方式 示例 java.lang.string
-
可以使用通配符.表示任意数据类型,但是必须有参数 * *..*.*(.)
-
可以再添加一个通配符.表示有无参数 * *..*.*(..)
-
-
可以根据需求添加需要的通配符
-
-
-
-
配置切入点表达式
-
标签:aop:pointcut
-
属性:id唯一标识,expression配置的表达式
-
分类
-
将aop:pointcut标签放置在aop:aspect标签内部的任何位置,只限于当前切面使用
-
将aop:pointcut标签只能放置在第一个aop:aspect标签外部的上方,任何切面都可以使用
-
<aop:pointcut id="pt1" expression="execution(* com.mypro.service.impl.*.*(..))"></aop:point>
完整的aop配置文件
<bean id="logger" class="com.mypro.service.impl.wordsserviceimpl"></bean> <aop:config> <aop:aspect id="loggeradvice" ref="logger"> <aop:pointcut id="pt1" expression="execution(* com.mypro.service.impl.*.*(..))"></aop:point> <aop:before method="beforeinfo" pointcut-ref="pt1"></aop:before> <aop:after-returning method="afterreturninginfo" pointcut-ref="pt1"></aop:after-returning> <aop:after-throwing method="afterthrowinginfo" pointcut-ref="pt1"></aop:after-throwing> <aop:after method="afterinfo" pointcut-ref="pt1"></aop:after> </aop:aspect> </aop:config>
-
-
环绕通知标签:aop:around。属性和其他通知标签的属性即作用一样,而环绕通知的功能就是通过编码完成上述4中通知标签的事情,而只需要在xml文件配置这一个环绕通知的标签即可,编码就在通知类中实现
<bean id="logger" class="com.mypro.service.impl.wordsserviceimpl"></bean> <aop:config> <aop:aspect id="loggeradvice" ref="logger"> <aop:pointcut id="pt1" expression="execution(* com.mypro.service.impl.*.*(..))"></aop:pointcut> <aop:around method="aroundinfo" poinitcut-ref="pt1"></aop:around> </aop:aspect> </aop:config>
然后在通知类中(这里是logger类)的aroundinfo方法编写类似上述四种通知的功能。
分析:通过动态代理中的环绕通知代码,发现动态代理的环绕通知有明确的切入点方法调用,而我们的方法没有
解决:spring框架为我们提供了一个接口,proceedingjoinpoint,该接口有一个proceed方法,此方法就相当于明确调用切入点方法,该接口可以作为环绕通知的方法参数,在程序执行时,spring框架会为我们提供该接口的实现类调用
import org.aspectj.lang.proceedingjoinpoint; public class logger{ public object aroundinfo(){ object rtvalue = null; try{ system.out.println("前置通知"); // 得到方法执行时所需的参数 object[] args = pjp.getargs(); // 明确调用业务层方法(切入点方法) rtvalue = pjp.proceed(args); system.out.println("后置通知"); return rtvalue; }catch(throwable t){ // 必须是用throwable捕捉异常 system.out.println("异常通知"); throw new runtimeexception(t); }finally{ system.out.println("最终通知"); } } }
-