【我看Spring】从一个简单的AOP示例看切面编程

 

       AOP(Aspect Oriented Programming),即面向切面编程,就是大家熟知的一些常见应用于监察很多不同类方法的事务性、安全性,对重点类方法、流程进行日志记录。这里Spring中谈到的AOP和Struts中的Filter性质类似,Filter也是能够通过配置文件配置好以后,进行特定类型访问筛选,并针对筛选对象进行某些指定操作。

       常见的AOP配置,就是在Spring的核心配置文件中进行<aop:config>配置,其实SSH框架中最突出常用的操作就是进行信息配置,将关键点、类方法注册到框架中,再通过框架集成的内部功能类解析,将配置信息进行匹配执行。SSH框架缓解或者基本解决了了大系统的高耦合度、不易扩展和维护难的问题。并且使得应用开发更加方便、快捷。

       更多的关于这些框架的总结,还是会在项目中不断使用框架的过程思考、沉淀。

       在Spring中配置使用AOP很简单,若要应用熟练还是要下功夫的,如下:

      1.  引入相关jar文件:aspectjrt.jar / aspectweaver.jar / cglib-nodep.jar

      2.  核心配置:依旧是在Spring核心配置文件 *.xml中

<?xml version="1.0" encoding="UTF-8"?>

 

<beans xmlns="http://www.springframework.org/schema/beans"

     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

     xmlns:aop="http://www.springframework.org/schema/aop"

     xmlns:tx="http://www.springframework.org/schema/tx"

     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd

           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd

           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

 

        <bean id="userManager" class="com.jzg.spring.UserManagerImpl"/>         

        <bean id="securityHandler" class="com.jzg.spring.SecurityHandler"/>

        

        <aop:config>

<!-- 先声明一个aspect,这里securityHandler为<bean id="securityHandler">所指向的java类 -->

        <!--securityHandler中有需要在被切入方法上执行的方法  -->

               <aop:aspect id = "securityAspect" ref="securityHandler">

               <!-- 这里是匹配任意返回值的无参add前缀 的方法 -->

               <!-- <aop:pointcut id="addAllMethod" expression="execution(* add*(..))"/>  -->

               

               <!-- execution(* com.jzg.spring.*.*(..)), 这里是匹配spring包下的所有方法 -->

                     <aop:pointcut id="AllMethod" expression="execution(* com.jzg.spring.*.*(..))"/>

                            <!-- 按照AllMethod切入点的规定,在spring包下所有方法执行后都会执行一次 checkSecurity() 方法 -->

               <aop:after method="checkSecurity" 

pointcut-ref="AllMethod"/>

                      

               </aop:aspect>

        </aop:config>

</beans>

 

     3.相关java类

      -----Client.java

package com.jzg.spring;

 

import org.springframework.beans.factory.BeanFactory;

import org.springframework.context.support.ClassPathXmlApplicationContext;

 

 

/**

 * @author jzg

 *

 */

public class Client {

 

 

  public static void main(String[] args) {

      

     BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");

     

     UserManager userManager = (UserManager)factory.getBean("userManager");

     

     //以下方法执行过程将会引入AOP相关方法的执行

     //addUser()方法

     userManager.addUser("张三","123");

     //delUser()方法

     userManager.delUser(0);

     //findUserById()方法

     userManager.findUserById(1);

     //modifyUser()方法

     userManager.modifyUser(1, "userName", "password");

     

  }

}

 

       --------SecurityHandler.java

package com.jzg.spring;

 

public class SecurityHandler  {

  @SuppressWarnings("unused")

  private void checkSecurity(){

     System.out.println("-------checkSecurity()----------");

  }

}

 

 

        ----------UserManager.java

package com.jzg.spring;

 

public interface UserManager {

 

  public void addUser(String userName ,String password);

  

  public void delUser(int userId);

  

  public String findUserById(int userId);

  

  public void modifyUser(int userId,String userName,String password);

  

}

 

 

       ----------UserManagerImpl.java

package com.jzg.spring;

 

public class UserManagerImpl implements UserManager {

 

 

    @Override

    public void delUser(int userId) {

       System.out.println("----UserManagerImpl.delUser()---");

 

    }

 

    @Override

    public String findUserById(int userId) {

       System.out.println("----UserManagerImpl.findUserById()---");

       return "zhangsan";

    }

 

    @Override

    public void modifyUser(int userId, String userName, String password) {

       System.out.println("----UserManagerImpl.modifyUser()---");

 

    }

 

    @Override

    public void addUser(String userName, String password) {

       System.out.println("----UserManagerImpl.addUser()---");

    }

    

}

 

 

       -----运行结果:

----UserManagerImpl.addUser()---

-------checkSecurity()----------

----UserManagerImpl.delUser()---

-------checkSecurity()----------

----UserManagerImpl.findUserById()---

-------checkSecurity()----------

----UserManagerImpl.modifyUser()---

-------checkSecurity()----------

 

 

        4.在这里只是简单的配置了一个AOP的应用实例,别没有进行深入复杂的配置和设计,仅用这个示例相信大家能很清楚的看到AOP几个关键概念之间的关系。分清楚这些关键概念,熟练应用到项目中还只是一个量的问题。

        5. 结合上面代码,简要说一下AOP中几个关键概念。

         切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”,“切面”在ApplicationContext中<aop:aspect>来配置。

         连接点(Joinpoint) :程序执行过程中的某一行为, 比较直接的体现就是在Client类中的userManager.addUser() /userManager.delUser()等方法行为。

        通知(Advice) :“切面”对于某个“连接点”所产生的动作,在applicationContext.xml中配置节点<aop:pointcut>下定义的method=”checkSecurity” 就是一个Advice,在这里就表现为我们需要在addUser()之后进行一下checkSecurity()检查。

        切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。就是定义哪些类里的哪些方法需要进行纵向切入,如

<aop:pointcut id="AllMethod" expression="execution(* com.jzg.spring.*.*(..))"/>

        目标对象(Target Object) :被一个或者多个切面所通知的对象。例如,UserManagerImpl类,因为它实现了UserManager中的方法,而那些方法就是要被进行切入 的。

         AOP代理(AOP Proxy): 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。

 

posted @ 2011-07-26 12:28  争光  阅读(226)  评论(0)    收藏  举报