一:springAOP前置通知、后置通知以及最终通知
前置通知就是在切入点前面执行方面体,后置就是在后面,最终就是返回之后。
下面以一个日志记录的案例介绍:
1:创建controller类
1 /** 2 * 3 */ 4 package com.hlcui.controller; 5 import org.springframework.stereotype.Controller; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 /** 8 * @author Administrator 9 * 10 */ 11 @Controller 12 @RequestMapping("/web") 13 public class HelloController { 14 15 @RequestMapping("/hello.form") 16 public String execute() throws Exception { 17 System.out.println("处理业务逻辑!"); 18 return "hello"; 19 } 20 21 }
2:创建方面组件
1 /** 2 * 3 */ 4 package com.hlcui.aspect; 5 6 7 /** 8 * @author Administrator 9 * 10 */ 11 public class OperatorLogger { 12 public void logger(){ 13 System.out.println("-->记录用户日志"); 14 } 15 }
3:声明方面组件
1 <!-- 配置日志组件 --> 2 <bean id="operatorLogger" class="com.hlcui.aspect.OperatorLogger"></bean>
4:将方面组件作用于目标组件上
1 <!-- 配置方面组件 --> 2 <aop:config> 3 <aop:aspect ref="operatorLogger"> 4 <aop:before method="logger" pointcut="within(com.hlcui.controller..*)"/> 5 </aop:aspect> 6 </aop:config>
5:测试方法
1 @Test 2 /**测试通过aop切入日志*/ 3 public void testAopPointCut() throws Exception { 4 String conf = "spring-mvc.xml"; 5 ApplicationContext ac = new ClassPathXmlApplicationContext(conf); 6 HelloController ctrl = ac.getBean("helloController", HelloController.class); 7 ctrl.execute(); 8 }
通过运行结果可以看出,在执行目标组件之前执行了方面组件,这是前置通知,如果想
后置通知或者最终通知,只需要将配置文件中的before修改为after与after-returning即可。
二:springAOP环绕通知
环绕通知相当于包括前置和后置
环绕通知使用案例如下:
1:在组件方面类中添加新的方法logger2
1 public Object logger2(ProceedingJoinPoint p ) throws Throwable{ 2 String targetName = p.getTarget().getClass().getName(); 3 String methodName = p.getSignature().getName(); 4 String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()); 5 String msg = date+"执行"+targetName+methodName; 6 System.out.println(msg); 7 Object obj = p.proceed(); 8 System.out.println("调用目标组件业务方法后"); 9 return obj; 10 }
2:组件的声明,在上一步前置通知时已经声明,这里不再声明
3:修改将方面组件用在目标组件上
1 <!-- 配置方面组件 --> 2 <aop:config> 3 <aop:aspect ref="operatorLogger"> 4 <aop:around method="logger2" pointcut="within(com.hlcui.controller..*)"/> 5 </aop:aspect> 6 </aop:config>
将before修改成around即可
4:测试方法
环绕通知已经成功切入!
三:springAOP异常通知
1:修改目标组件,故意制造一个错误
1 /** 2 * 3 */ 4 package com.hlcui.controller; 5 import org.springframework.stereotype.Controller; 6 import org.springframework.web.bind.annotation.RequestMapping; 7 /** 8 * @author Administrator 9 * 10 */ 11 @Controller 12 @RequestMapping("/web") 13 public class HelloController { 14 15 @RequestMapping("/hello.form") 16 public String execute() throws Exception { 17 System.out.println("处理业务逻辑!"); 18 Integer i = 1/0; 19 System.out.println(i); 20 return "hello"; 21 } 22 23 }
2:在方面组件类中添加一个logger3方法
1 public void logger3(Exception e){ 2 StackTraceElement[] eles = e.getStackTrace(); 3 System.out.println(eles[0].toString()); 4 }
3:在配置文件中配置异常通知
1 <!-- 配置方面组件 --> 2 <aop:config> 3 <aop:aspect ref="operatorLogger"> 4 <aop:before method="logger" pointcut="within(com.hlcui.controller..*)"/> 5 </aop:aspect> 6 7 <aop:aspect ref="operatorLogger"> 8 <aop:around method="logger2" pointcut="within(com.hlcui.controller..*)"/> 9 </aop:aspect> 10 11 <aop:aspect ref="operatorLogger"> 12 <aop:after-throwing method="logger3" throwing="e" pointcut="within(com.hlcui.controller..*)"/> 13 </aop:aspect> 14 </aop:config> 15
4:测试方法
通过结果可以看出异常通知成功切入!