Java基础-SSM之Spring的AOP编程
Java基础-SSM之Spring的AOP编程
作者:尹正杰
版权声明:原创作品,谢绝转载!否则将追究法律责任。
Spring的本质说白了就是动态代理,接下来我们会体验AOP的用法。它是对OOP的增强,适用于系统级功能。
一.MethodBeforeAdvice接口的应用
1>.引入新的依赖
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>cn.org.yinzhengjie</groupId> 8 <artifactId>MySpring</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <dependencies> 12 <dependency> 13 <groupId>junit</groupId> 14 <artifactId>junit</artifactId> 15 <version>4.11</version> 16 </dependency> 17 <dependency> 18 <groupId>org.springframework</groupId> 19 <artifactId>spring-context-support</artifactId> 20 <version>4.3.5.RELEASE</version> 21 </dependency> 22 23 <dependency> 24 <groupId>aopalliance</groupId> 25 <artifactId>aopalliance</artifactId> 26 <version>1.0</version> 27 </dependency> 28 </dependencies> 29 30 </project>
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 <?xml version="1.0"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.3.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> 15 <!-- 前置通知 --> 16 <bean id="beforeAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyMethodBeforeAdvice" /> 17 18 <!-- 目标对象 --> 19 <bean id="wsTarget" class="cn.org.yinzhengjie.spring.aop.advice.WelcomeServiceImpl"> 20 <property name="name" value="I'm yinzhengjie !!!" /> 21 </bean> 22 23 <!-- 代理对象 --> 24 <bean id="wsProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> 25 <!-- 代理接口集 --> 26 <property name="proxyInterfaces"> 27 <list> 28 <value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService</value> 29 <value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService2</value> 30 </list> 31 </property> 32 <!-- 拦截器名集合 --> 33 <property name="interceptorNames"> 34 <list> 35 <value>beforeAdvice</value> 36 </list> 37 </property> 38 39 <!-- 注意,目标类的名字为"target"关键字,而ref是真正需要被代理的对象连接。一个代理对象一次性只能代理一个类,如果想要代理多个类,需要重新单独定义bean标签哟! --> 40 <property name="target" ref="wsTarget" /> 41 42 </bean> 43 </beans>
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 @Test 14 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 <?xml version="1.0"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation="http://www.springframework.org/schema/beans 8 http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 9 http://www.springframework.org/schema/aop 10 http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 11 http://www.springframework.org/schema/context 12 http://www.springframework.org/schema/context/spring-context-4.3.xsd 13 http://www.springframework.org/schema/tx 14 http://www.springframework.org/schema/tx/spring-tx-4.3.xsd"> 15 <!-- 通知 --> 16 <bean id="beforeAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyMethodBeforeAdvice" /> 17 <bean id="afterAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyAfterReturningAdvice" /> 18 <bean id="aroundAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyMethodInterceptor" /> 19 <bean id="throwableAdvice" class="cn.org.yinzhengjie.spring.aop.advice.MyThrowableAdvice" /> 20 21 22 <!-- 目标对象 --> 23 <bean id="wsTarget" class="cn.org.yinzhengjie.spring.aop.advice.WelcomeServiceImpl"> 24 <property name="name" value="tom" /> 25 </bean> 26 27 <!-- 代理对象 --> 28 <bean id="wsProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> 29 <!-- 代理接口集 --> 30 <property name="proxyInterfaces"> 31 <list> 32 <value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService</value> 33 <value>cn.org.yinzhengjie.spring.aop.advice.WelcomeService2</value> 34 </list> 35 </property> 36 <!-- 拦截器名集合 --> 37 <property name="interceptorNames"> 38 <list> 39 <value>beforeAdvice</value> 40 <value>afterAdvice</value> 41 <value>aroundAdvice</value> 42 <value>throwableAdvice</value> 43 </list> 44 </property> 45 <property name="target" ref="wsTarget" /> 46 </bean> 47 </beans>
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 @Test 14 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>.运行以上代码执行结果如下:
本文来自博客园,作者:尹正杰,转载请注明原文链接:https://www.cnblogs.com/yinzhengjie/p/9288904.html,个人微信: "JasonYin2020"(添加时请备注来源及意图备注,有偿付费)
当你的才华还撑不起你的野心的时候,你就应该静下心来学习。当你的能力还驾驭不了你的目标的时候,你就应该沉下心来历练。问问自己,想要怎样的人生。