首先配置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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
将对象交由factory
很有趣的是,双标签如果挨着一块,不分开就会警告= =!
不过都是不影响的,只是不太美观
<bean class="transaction" id="transaction"> </bean>
<bean class="Mybefore" id="mybefore"></bean>
这里通俗详细的介绍了流程
<!-- 3:配置aop -->
**<aop:config>**
<!-- 切入点:拦截哪些bean的方法 -->
<!-- 通俗的来说:就是程序运行到哪里,将会拦截下来,然后读取你所配置的的增强通知-->
<!-- 而bean(*xxx) -->表示拦截的bean跟上面配置的bean的id关联,
而*xxx表示以xxx的最后三个字母作为拦截依据,如果是bean(*xx)则为最后两个xx作为拦截依据
而bean(xx*)则为前缀,一样的道理。
<aop:pointcut id="entrypoint" expression="bean(*transaction)"/>
<!--切面:-->
<!--ref:填写你的通知bean,就是上面的bean的id-->
<aop:aspect ref="xxxx">
<!-pointcut-ref="xxx":注入切入点
目的是让通知关联切入点-->
<!-- method:填写通知bean里面你的通知方法,before则是通知类型-->
<!--pointcut-ref:"填写上面 <aop:pointcut id="entrypoint" expression="bean(*transaction)"/>的id,
也就是你配置的拦截的bean的id"-->
<aop:before method="myBefore" pointcut-ref="entrypoint"/>
</aop:aspect>
**</aop:config>**
所有通知的标签属性
<!--
前置通知,在切入点方法之前执行
<aop:before method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
返回成功通知,在切入点方法执行成功之后执行
<aop:after-returning method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
返回异常通知,在切入点方法抛出异常后执行
<aop:after-throwing method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
最终通知,不管切入点方法执行成功还是抛出异常都会执行
<aop:after method="log" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
<!--
环绕通知,在切入点方法执行前后都可以执行,需要在增强方法参数引入ProceedingJoinPoint,
然后在增强方法中ProceedingJoinPoint.proceed()方法控制切入点方法的执行
<aop:around method="logAround" pointcut="execution(* com.yooyo.service.*.*ServiceImpl.findAll(..))"/>
-->
另外我还准备了一些配置拦截bean的表达式列子
1:modifiers-pattern? (非必填项):表示方法的修饰符
execution(public void cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示:共有方法,无返回类型,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(private void cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示:私有方法,无返回类型,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
2:ret-type-pattern (必填项):表示方法的返回类型
execution(void cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示:无返回类型,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(java.lang.String cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示:返回类型String类型,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示:返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
3:declaring-type-pattern? (非必填项):表示包,或者子包的,或者类的修饰符
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(* cn.itcast.e_xml.*.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml包中的所有子包,包中UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(* cn.itcast.e_xml.*.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml包中的所有类,类中的saveUser方法,参数2个,都是String类型
execution(* cn.itcast.e_xml..*.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml包中及其子包中的所有类,类中的saveUser方法,参数2个,都是String类型
execution(* *.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,所有包中的所有类,类中的saveUser方法,参数2个,都是String类型
execution(* saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,所有包中的所有类,类中的saveUser方法,参数2个,都是String类型
4:name-pattern(param-pattern)(必填项):方法的名称(方法的参数)
(1)方法名称
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.save*(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的以save开头的方法,参数2个,都是String类型
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.*(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的所有方法,参数2个,都是String类型
(2)方法的参数
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.String))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,都是String类型
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,java.lang.Integer))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,参数1是String类型,参数二是Integer
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(java.lang.String,*))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数2个,参数1是String类型,参数二是任意类型
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(*))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数1个,参数是任意类型
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser())
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,没有参数
execution(* cn.itcast.e_xml.a_before.UserServiceImpl.saveUser(..))
* 表示返回类型任意,cn.itcast.e_xml.a_before包中的UserServiceImpl类,类中的saveUser方法,参数任意(可以是0个,也可以多个)
5:throws-pattern?(非必填项):方法上抛出的异常
项目开发中表达式(最多用)
1:execution(* cn.itcast.procject.service..*.*(..))
* 返回类型任意,cn.itcast.procject.service包及其子包中所有类,类中所有方法,参数任意
2:execution(* *..*.*(..))
* 返回类型任意,任意包中及其子包中所有类,类中所有方法,参数任意
3:execution(* *(..))
* 返回类型任意,任意包中及其子包中所有类,类中所有方法,参数任意
下面给出一些通用切入点表达式的例子。
任意公共方法的执行:
execution(public * *(..))
任何一个名字以“set”开始的方法的执行:
execution(* set*(..))
AccountService接口定义的任意方法的执行:
execution(* com.xyz.service.AccountService.*(..))
在service包中定义的任意方法的执行:
execution(* com.xyz.service.*.*(..))
在service包或其子包中定义的任意方法的执行:
execution(* com.xyz.service..*.*(..))