4. 编写切面类AspectBean,代码如下
[Java]
package com.trs.components.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; /** * 拦截StudentMgr的切面 * * */ @Aspect // 声明一个切面 public class AspectBean { @Before("execution (* com.trs.components.mgr.StudentMgr.update*(..))") // 声明前置通知,拦截StudentMgr的所有以update开头的方法 public void validateUser(JoinPoint pjp) throws Throwable { System.out.println("执行用户验证!"); } @Before("execution (* com.trs.components.mgr.StudentMgr.update*(..))") // 声明前置通知,拦截StudentMgr的所有以update开头的方法 public void beginTransaction(JoinPoint _jp) throws Throwable { // 如果需要对连接点传入的参数进行处理,可以通过代码获取:_jp.getArgs(); System.out.println("开始事务"); } @After("execution (* com.trs.components.mgr.StudentMgr.update*(..))") // 声明最终通知,拦截StudentMgr的所有以update开头的方法 public void endTransaction() throws Throwable { System.out.println("结束事务"); } @After("execution (* com.trs.components.mgr.StudentMgr.update*(..))") // 声明最终通知,拦截StudentMgr的所有以update开头的方法 public void writeLogInfo() { System.out.println("记录日志信息"); } @AfterThrowing(pointcut = "execution (* com.trs.components.mgr.StudentMgr.update*(..))", throwing = "ex") // 声明异常,StudentMgr类的update方法出现异常时执行 public void printException(Exception ex) { System.out.println("执行update方法时发生错误" + ex.getMessage()); } @Around("execution (* com.trs.components.mgr.StudentMgr.update*(..))") // 声明环绕通知,拦截StudentMgr的所有以update开头的方法 public Object doSurround(ProceedingJoinPoint _pjp)throws Throwable { // 如果需要对连接点传入的参数进行处理,可以通过代码获取:pjp.getArgs(); Object result; if (true) { // 这里可以根据条件决定是否进入这个if System.out.println("进入环绕通知..."); result = _pjp.proceed();// 使用环绕通知时,这个方法必须要执行,否则被拦截的方法就不会再执行了 System.out.println("退出环绕通知..."); } // 返回执行后的返回值 return result; } }说明:
[1] @Before("execution (* com.trs.components.mgr.StudentMgr.update*(..))") 第一个*号表示匹配方法的返回值可以使任何类型;第二个*号表示所有以update开头的方法都会被拦截;(..)表示这些方法输入的参数可以0或者多个。
[2] @AfterThrowing中的 throwing = "ex",表示方法出错的时候会返回一个名称为ex的异常,在切入点中通过参数ex即可获取到出错的异常对象。
[3] 环绕方法doSurround的写法需要注意
l 环绕方法中的第一个参数类型必须是ProceedingJoinPoint类型(环绕的方法名可以随便起名)。
l 环绕方法抛的异常需要时Throwable类型
l 环绕方法中需要执行_pjp.proceed()方法,否则被拦截的方法不会执行
l 在_pjp.proceed()方法前后各加一个时间点,可以用来测试被拦截的方法的执行时间
5. 切面类的一些bean配置
在Spring的配置文件中加入如下代码,配置相关的bean类。
<?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
">
<bean />
<bean></bean>
<bean></bean>
</beans>
6. 编写测试用例
利用Junit编写测试StudentMgr.update方法的测试用例,测试用例相关方法代码如下:
@Test
public void testUpdate() throws Exception {
// 使用ApplicationContext来初始化系统
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
IStudentMgr studentMgr = (IStudentMgr) context.getBean("IStudentMgr");
// studentMgr.saveOne("wuguowei");
System.out.println("-----------");
studentMgr.update("wuguowei");
}
7. 执行测试用例,查看打印结果
开始事务
执行用户验证!
进入环绕通知...
更新了学生对象..
结束事务
记录日志信息
退出环绕通知...
8. 实例对应的XML配置的AOP编程
上面我们给出的是注解风格的AOP编程,上面实例的编程同样可以采用XML配置方式的AOP编程,我们只需要在Spring的配置文件中添加如下代码即可(AOP的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
">
<aop:config>
<aop:aspect ref="aspectBean">
<aop:pointcut expression="execution (* com.trs.components.mgr.StudentMgr.update*(..))"/>
<aop:before pointcut-ref="mypointcut" method="validateUser"/>
<aop:before pointcut-ref="mypointcut" method="beginTransaction"/>
<aop:after pointcut-ref="mypointcut" method="endTransaction"/>
<aop:after pointcut-ref="mypointcut" method="writeLogInfo"/>
<aop:after-throwing pointcut-ref="mypointcut" method="printException"/>
<aop:around pointcut-ref="mypointcut" method="doSurround"/>
</aop:aspect>
</aop:config>
<bean />
<bean></bean>
<bean></bean>
<bean></bean>
</beans>