Java基础-SSM之Spring的AOP编程
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
Spring的本质说白了就是动态代理,接下来我们会体验AOP的用法。它是对OOP的增强,适用于系统级功能。
一.MethodBeforeAdvice接口的应用
1>.引入新的依赖
1 25 4.0.0 6 7cn.org.yinzhengjie 8MySpring 91.0-SNAPSHOT 10 1112 29 3013 17junit 14junit 154.11 1618 22 23org.springframework 19spring-context-support 204.3.5.RELEASE 2124 28aopalliance 25aopalliance 261.0 27
2>.定义通知类
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.springframework.aop.MethodBeforeAdvice; 9 10 import java.lang.reflect.Method;11 12 /**13 * 前置通知14 */15 public class MyMethodBeforeAdvice implements MethodBeforeAdvice {16 public void before(Method method, Object[] args, Object target) throws Throwable {17 String mname = method.getName() ;18 System.out.printf("当前处理的对象 : %s\n调用对象的方法 : %s\n调用参数 : %s\n" , target.toString(),mname.toString(),args.toString());19 System.out.println("============= MyMethodBeforeAdvice代码执行完毕 =============");20 }21 }
3>.编写实现WelcomeService和WelcomeService2两个接口的类
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 public interface WelcomeService { 9 public abstract void sayHello();10 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 public interface WelcomeService2 { 9 public abstract void sayHello2();10 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 9 public class WelcomeServiceImpl implements WelcomeService,WelcomeService2{10 private String name ;11 12 public String getName() {13 return name;14 }15 16 public void setName(String name) {17 this.name = name;18 }19 20 public void sayHello() {21 System.out.println(name);22 }23 24 public void sayHello2() {25 System.out.println("Hello Wold");26 }27 }
4>.编写Spring的配置文件
1 215 16 17 18 19 20 22 23 2421 25 26 4327 32 3328
31cn.org.yinzhengjie.spring.aop.advice.WelcomeService 29cn.org.yinzhengjie.spring.aop.advice.WelcomeService2 3034 38 39 4035
37beforeAdvice 3641 42
5>.编写单元测试类代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.junit.Test; 9 import org.springframework.context.ApplicationContext;10 import org.springframework.context.support.ClassPathXmlApplicationContext;11 12 public class TestAop {13 @Test14 public void testAOP1(){15 ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml") ;16 WelcomeService ws = (WelcomeService) ac.getBean("wsProxy");17 ws.sayHello();18 19 WelcomeService2 ws2 = (WelcomeService2)ws;20 ws2.sayHello2();21 22 }23 }
以上代码测试结果如下:
二.AOP的四个通知编程案例
上面我们已经介绍了Spring的AOP编程中的一个前置通知,其实除了前置通知还有后置通知,循环通知以及异常通知。其实配置文件的方法和上面类似,只不过他们有各自的优点,下面我简单的做个介绍:
前置通知:主要负责处理调用目标对象之前执行的代码;
后置通知:主要负责处理调用目标对象之后的执行代码;
环绕通知:它执行的优先级是在后置通知之前,在前置通知之后的执行的代码,它可以把方法包起来处理,比如在调用方法之前执行一段代码,在调用方法之后,还可以执行一段代码,另外,相比前置通知和通知通知,它还新增了一个返回值的功能;
异常通知:它执行的优先级暂时没法确定,而且不一定执行,顾名思义,它是在有异常的时候才会触发的代码!因此即使你写了这样的通知,有可能你看不到它的执行结果,除非你故意写一段可能出现异常的代码;
1>.编写测试代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 public interface WelcomeService { 9 public abstract void sayHello();10 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 public interface WelcomeService2 { 9 public abstract void sayHello2();10 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 9 public class WelcomeServiceImpl implements WelcomeService,WelcomeService2{10 private String name ;11 12 public String getName() {13 return name;14 }15 16 public void setName(String name) {17 this.name = name;18 }19 20 public void sayHello() {21 System.out.println(name);22 }23 24 public void sayHello2() {25 System.out.println("Hello Wold");26 }27 }
2>.编写通知类
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.springframework.aop.MethodBeforeAdvice; 9 10 import java.lang.reflect.Method;11 12 /**13 * 前置通知14 */15 public class MyMethodBeforeAdvice implements MethodBeforeAdvice {16 public void before(Method method, Object[] args, Object target) throws Throwable {17 String mname = method.getName() ;18 System.out.printf("当前处理的对象 : %s\n调用对象的方法 : %s\n调用参数 : %s\n" , target.toString(),mname.toString(),args.toString());19 System.out.println("============= MyMethodBeforeAdvice代码执行完毕 =============");20 }21 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.aopalliance.intercept.MethodInterceptor; 9 import org.aopalliance.intercept.MethodInvocation;10 11 /**12 * 环绕通知,可以篡改行为13 */14 public class MyMethodInterceptor implements MethodInterceptor {15 16 public Object invoke(MethodInvocation invocation) throws Throwable {17 System.out.println("begin");18 //调用目标对象方法的返回值19 Object tis = invocation.getThis();20 System.out.println(tis);21 Object ret = invocation.proceed() ;22 System.out.println("end");23 return ret;24 }25 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.springframework.aop.AfterReturningAdvice; 9 10 import java.lang.reflect.Method;11 12 public class MyAfterReturningAdvice implements AfterReturningAdvice {13 public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {14 System.out.println("over");15 }16 }
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.springframework.aop.ThrowsAdvice; 9 10 import java.lang.reflect.Method;11 12 /**13 * 异常通知14 */15 public class MyThrowableAdvice implements ThrowsAdvice {16 public void afterThrowing(Method method, Object[] args, Object target, Exception ex){17 System.out.println("出事了!!" + ex.toString());18 }19 }
3>.编写Spring的配置文件
1 215 16 17 18 19 20 21 22 23 24 26 27 2825 29 30 4731 36 3732
35cn.org.yinzhengjie.spring.aop.advice.WelcomeService 33cn.org.yinzhengjie.spring.aop.advice.WelcomeService2 3438 4539
44beforeAdvice 40afterAdvice 41aroundAdvice 42throwableAdvice 4346
4>.编写测试代码
1 /* 2 @author :yinzhengjie 3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Java%E5%9F%BA%E7%A1%80/ 4 EMAIL:y1053419035@qq.com 5 */ 6 package cn.org.yinzhengjie.spring.aop.advice; 7 8 import org.junit.Test; 9 import org.springframework.context.ApplicationContext;10 import org.springframework.context.support.ClassPathXmlApplicationContext;11 12 public class TestAop {13 @Test14 public void testAOP1(){15 ApplicationContext ac = new ClassPathXmlApplicationContext("aop.xml") ;16 WelcomeService ws = (WelcomeService) ac.getBean("wsProxy");17 ws.sayHello();18 19 WelcomeService2 ws2 = (WelcomeService2)ws;20 ws2.sayHello2();21 22 }23 }
5>.运行以上代码执行结果如下: