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
调用对象的方法 : %s
调用参数 : %s
" , 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 }
WelcomeService.java 文件内容
 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 }
WelcomeService2.java 文件内容
 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 }

  以上代码测试结果如下:

Java基础-SSM之Spring的AOP编程

二.AOP的四个通知编程案例

  上面我们已经介绍了Spring的AOP编程中的一个前置通知,其实除了前置通知还有后置通知,循环通知以及异常通知。其实配置文件的方法和上面类似,只不过他们有各自的优点,下面我简单的做个介绍:

    前置通知:主要负责处理调用目标对象之前执行的代码;

    后置通知:主要负责处理调用目标对象之后的执行代码;

    环绕通知:它执行的优先级是在后置通知之前,在前置通知之后的执行的代码,它可以把方法包起来处理,比如在调用方法之前执行一段代码,在调用方法之后,还可以执行一段代码,另外,相比前置通知和通知通知,它还新增了一个返回值的功能;

    异常通知:它执行的优先级暂时没法确定,而且不一定执行,顾名思义,它是在有异常的时候才会触发的代码!因此即使你写了这样的通知,有可能你看不到它的执行结果,除非你故意写一段可能出现异常的代码;

Java基础-SSM之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 }
WelcomeService.java 文件内容
 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 }
WelcomeService2.java 文件内容
 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 }
WelcomeServiceImpl.java 文件内容

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
调用对象的方法 : %s
调用参数 : %s
" , target.toString(),mname.toString(),args.toString());
19         System.out.println("============= MyMethodBeforeAdvice代码执行完毕 =============");
20     }
21 }
MyMethodBeforeAdvice.java 文件内容
 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 }
MyMethodInterceptor.java 文件内容
 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 }
MyAfterReturningAdvice.java 文件内容
 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 }
MyThrowableAdvice.java 文件内容

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>.运行以上代码执行结果如下:

Java基础-SSM之Spring的AOP编程

相关推荐