你的位置:首页 > Java教程

[Java教程]spring笔记


  Spring的另一个重要思想是AOP,面向切面的编程,它提供了一种机制,可以在执行业务前后执行另外的代码,Servlet中的Filter就是一种AOP思想的体现,下面通过一个例子来感受一下.

  假设我们现在需要在针对数据库进行CRUD操作时添加一组日志,即在执行CRUD方法前后分别加上一句话,实现简单的面向切面编程的功能.我用到的是spring4,在配置文件上较之之前的版本可能有些不同.

  使用springAPI来实现AOP,除了spring必不可少的核心jar包,还需要两个jar包需要导入:

    1.   aspectjweaver.jar   下载链接: http://download.csdn.net/detail/luojiming1990/5432831
    2.   aopalliance.jar    下载链接:http://download.csdn.net/detail/zhaoshe/3153090

  并且配置文件的头文件也需要略作修改,详见下面实例中的beans.

  UserService类(省略数据库操作代码,只做简单的打印来模拟):

public class UserService {  public void add(){    System.out.println("添加用户");  }  public void delete(){    System.out.println("删除用户");  }  public void update(){    System.out.println("修改用户");  }  public void search(){    System.out.println("查询用户");  }}

Log类(在执行增删改查方法前执行):

public class Log implements MethodBeforeAdvice{  /***   * method:被调用的方法对象   * arg1:被调用的方法的参数   * target:被调用方法的目标对象   */  @Override  public void before(Method method, Object[] arg1, Object target)      throws Throwable {    System.out.println(target.getClass().getName()+"中的"+method.getName()+"方法被执行");  }}

AfterLog类(在执行增删改查方法后执行):

public class AfterLog implements AfterReturningAdvice{  /**   * returnValue:返回值类型   * method:被调用的方法对象   * arg1:被调用的方法的参数   * target:被调用方法的目标对象   */  @Override  public void afterReturning(Object returnValue, Method method,      Object[] args, Object target) throws Throwable {        System.out.println(target.getClass().getName()+"中的"+method.getName()+"方法被执行成功,返回值是"+returnValue);     }

spring配置文件(beans.

<??><beans ="http://www.springframework.org/schema/beans"  ="http://www.w3.org/2001/  ="http://www.springframework.org/schema/aop"  xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans.xsd    http://www.springframework.org/schema/aop    http://www.springframework.org/schema/aop/spring-aop.xsd">  <bean id="userService" class="com.wang.service.UserService"></bean>  <bean id="log" class="com.wang.log.Log"></bean>  <bean id="afterlog" class="com.wang.log.AfterLog"></bean>  <aop:config>  <!--"*"为通配符表示所有方法       ".."表示任意个数的参数 -->    <aop:pointcut expression="execution(* com.wang.service.UserService.*())" id="pointcut"/>      <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>      <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>  </aop:config></beans>

测试代码testDemo:

  @Test  public void test1(){    ApplicationContext context=new ClassPath);    UserService userService=(UserService)context.getBean("userService");    userService.add();    userService.search();  }

运行测试可以看到控制台的打印结果:

com.wang.service.UserService中的add方法被执行
添加用户
com.wang.service.UserService中的add方法被执行成功,返回值是null

com.wang.service.UserService中的search方法被执行
查询用户
com.wang.service.UserService中的search方法被执行成功,返回值是null

在配置文件中,我们看到了一些这样的代码:

 <aop:config>  <!--"*"为通配符表示所有方法       ".."表示任意个数的参数 -->    <aop:pointcut expression="execution(* com.wang.service.UserService.*())" id="pointcut"/>      <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>      <aop:advisor advice-ref="afterlog" pointcut-ref="pointcut"/>  </aop:config>

我们来介绍几个AOP的相关概念,这个就比较好理解了:

  • 切面(Aspect):在本例中.add(),delete(),等方法中都有一些代码,在真实的程序中这里不会只是简单的打印语句而是一些有意义的代码,这些代码可以看做是AOP的切面.
  • 通知(Advisor):本例中的两个日志类,这里可以成为拦截器,都是实现了某个*Advisor接口,这两个类就是指AOP中的通知,一旦Spring符合了条件,就会发出通知,与生活中我们所说的通知不同的是,Spring中的通知是带有执行代码的,能实现某种功能.
  • 切入点(pointcut):在配置拦截器(<aop-config>)的时候,

简而言之:"切入点"负责往"什么地方"插入代码,"通知"负责插入"什么代码".