SpringAOP的示例分析

这篇文章主要为大家展示了“Spring AOP的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Spring AOP的示例分析”这篇文章吧。

10余年建站经验, 成都网站设计、成都做网站客户的见证与正确选择。创新互联提供完善的营销型网页建站明细报价表。后期开发更加便捷高效,我们致力于追求更美、更快、更规范。

Spring中对AOP的支持

Spring中AOP代理由Spring的IoC容器负责生成、管理,其依赖关系也由IoC容器负责管理。因此,AOP代理可以直接使用容器中的其他Bean实例作为目标,这种关系可由IoC容器的依赖注入提供。Spring默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了。当需要代理的类不是代理接口的时候,Spring自动会切换为使用CGLIB代理,也可强制使用CGLIB。

本例子的逻辑如下:有一个Car类(业务类),在Car类中的go方法运行之前和之后,都会有相应的日志记录,但Car类本身并不知道日志的任何逻辑。

创建Maven项目并添加依赖

首先,新建一个Maven项目,使用 maven‐archetype‐quickstart模板,然后打开pom.xml文件,加入Spring AOP运行需要的依赖包


  org.springframework
  spring-core
  4.0.5.RELEASE


  org.springframework
  spring-beans
  4.0.5.RELEASE


  org.springframework
  spring-context
  4.0.5.RELEASE


  org.springframework
  spring-aop
  4.0.5.RELEASE


  org.aspectj
  aspectjweaver
  1.8.1

编写业务代码

新增一个业务类Car,包含一个go()方法

package com.wowo.spring_aop_demo1;
public class Car {
  public void go(){
    System.out.println("go go go!");
  }
}

编写切面类

日志类会记录下系统的运行情况,但日志的逻辑不会在业务类中写的到处都是,而是作为一个切面类存在。

package com.wowo.spring_aop_demo1;
public class CarLogger {
  public void beforeRun(){
    System.out.println("car is going to run");
  }
  public void afterRun(){
    System.out.println("car is running");
  }
}

该切面类包含两个方法,他们分别是前置通知和后置通知。

通过bean来配置关联

新增一个配置文件,本例命名为bean.xml,在配置文件中来关联切面与通知



  
  
  
    
      

      
      
    
  

注意:这个配置文件中,aop的命名空间,以及xsi:schemaLocation中包含的几个地址都是必须的。
execution(* com.wowo.spring_aop_demo1.Car.go(..))是一个AspectJ切点表达式,execution表示在执行时触发,后面的*表示任意类型的返回值,com.wowo.spring_aop_demo1.Car指的是切点所在的类,go(..)是方法名,..表示任意参数。

Spring切面可以应用5种类型的通知:

·Before——在方法被调用之前调用通知
·After——在方法完成之后调用通知,无论方法是否执行成功
·After-returning——在方法成功执行之后调用通知
·After-throwing——在方法抛出异常后调用通知
·Around——通知包裹了被通知的方法,在被通知的方法调用之前和调用之后都执行自定义的行为

运行业务代码

下面创建一个包含main()方法的类,来运行业务代码

package com.wowo.spring_aop_demo1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App 
{
  public static void main( String[] args )
  {
    ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
    Car car=(Car) context.getBean("car");
    car.go();
  }
}

在上面的代码中,由Spring创建了一个car对象。Spring在创建该对象时,发现它的一个方法被配置成了切点(pointcut),所以,在实例化该对象时,会创建一个代理对象,当切点方法go()执行时,会被Spring创建的代理对象所拦截,运行go方法之前,会调用所对应的切面类CarLogger的前置方法beforeRun(),然后调用Car.go()方法,再然后就调用切面类CarLogger的后置方法afterRun()。

注意:必须使用Spring创建包含切点的对象,如果自己创建的话,Spring是监测不到的,它的运行也不会被应用任何通知。

项目输出结果为

car is going to run
go go go!
car is running

使用环绕通知

如果想使用环绕通知,我们需要修改切面类中的通知方法以及配置文件,业务类无需做任何修改,因为他们是完全解耦的。首先修改切面类CarLogger

import org.aspectj.lang.ProceedingJoinPoint;
public class CarLogger {

  public void aroundRun(ProceedingJoinPoint joinpoint){
    System.out.println("car is going to run");
    try {
      //调用被代理的对象的目标方法,本例中指向Car.go()方法
      joinpoint.proceed();
    } catch (Throwable e) {
      e.printStackTrace();
    }
    System.out.println("car is running");
  }
}

环绕通知的方法,需要接受ProceedingJoinPoint类型的参数,其proceed()方法将会调用被代理对象的目标方法,所以,正常情况下,这个方法一定要调用。我们也可以通过不调用该方法来组织被代理对象的运行。

接下来将配置文件的aop:config部分修改为如下所示


    
      
      
    
  

注意:环绕通知不能和前置/后置通知同时存在。运行代码后,输出结果不变。

以上是“Spring AOP的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注创新互联行业资讯频道!


网页标题:SpringAOP的示例分析
标题来源:http://myzitong.com/article/gsecpe.html