zoukankan      html  css  js  c++  java
  • 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 }

      以上代码测试结果如下:

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

  • 相关阅读:
    js数据结构Map -----字典
    配置一个高效快速的Git环境
    Ubuntu下dlib库编译安装
    空间域二阶统计纹理
    Markdown语法
    Notepad++中NppExec的使用之一:基本用法
    斯坦福大学机器学习笔记及代码(一)
    安家落户
    Android App开发常用专题开源代码
    Android基础-EditText键盘的显示与隐藏
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/9288904.html
Copyright © 2011-2022 走看看