城市猎人

在一网情深的日子里,谁能说得清是苦是甜,只知道确定了就义无反顾
posts - 1, comments - 7, trackbacks - 0, articles - 89

spring aop总结

Posted on 2009-04-29 09:06 sailor 阅读(415) 评论(0)  编辑  收藏 所属分类: spring

一、Spring AOP相关术语

  • 切面(Aspect): 一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)来实现。

  • 连接点(Joinpoint): 在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。 在Spring AOP中,一个连接点 总是 代表一个方法的执行。 通过声明一个org.aspectj.lang.JoinPoint类型的参数可以使通知(Advice)的主体部分获得连接点信息。

  • 通知(Advice): 在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。 通知的类型将在后面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链。

  • 切入点(Pointcut): 匹配连接点(Joinpoint)的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。 切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。

  • 引入(Introduction): (也被称为内部类型声明(inter-type declaration))。声明额外的方法或者某个类型的字段。 Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。 例如,你可以使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制。

  • 目标对象(Target Object): 被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做 被通知(advised) 对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个 被代理(proxied) 对象。

  • AOP代理(AOP Proxy): AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 注意:Spring 2.0最新引入的基于模式(schema-based)风格和@AspectJ注解风格的切面声明,对于使用这些风格的用户来说,代理的创建是透明的。

  • 织入(Weaving): 把切面(aspect)连接到其它的应用程序类型或者对象上,并创建一个被通知(advised)的对象。 这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。 Spring和其他纯Java AOP框架一样,在运行时完成织入。

通知的类型:

  • 前置通知(Before advice): 在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

  • 返回后通知(After returning advice): 在某连接点(join point)正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。

  • 抛出异常后通知(After throwing advice): 在方法抛出异常退出时执行的通知。

  • 后通知(After (finally) advice): 当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。

  • 环绕通知(Around Advice): 包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法


二、使用注解方式
1、定义一个切面Aspect
 1package com.bjsxt.spring;
 2
 3import org.aspectj.lang.annotation.Aspect;
 4import org.aspectj.lang.annotation.Before;
 5import org.aspectj.lang.annotation.Pointcut;
 6
 7/**
 8 * 定义Aspect
 9 */

10@Aspect //一个关注点的模块化,这个关注点可能会横切多个对象。
11public class SecurityHandler {
12    
13    /**
14     * 定义Pointcut,Pointcut的名称就是allAddMethod,此方法不能有返回值和参数,该方法只是一个
15     * 标识
16     * 
17     * Pointcut的内容是一个表达式,描述那些对象的那些方法(订阅Joinpoint)
18     */

19    @Pointcut("execution(* add*(..)) || execution(* del*(..)) || execution(* mod*(..))")
20    private void allAddMethod(){};
21    
22    /**
23     * 定义Advice,标识在那个切入点何处织入此方法
24     */

25    @Before("allAddMethod()")
26    private void checkSecurity() {
27        System.out.println("----------checkSecurity()---------------");
28    }

29    
30}

31

2、用户管理业务处理接口
 1public interface UserManager {
 2
 3    public void addUser(String username, String password);
 4    
 5    public void deleteUser(int id);
 6    
 7    public void modifyUser(int id, String username, String password);
 8    
 9    public String findUserById(int id);
10}

3、接口实现
 1public class UserManagerImpl implements UserManager {
 2
 3    public void addUser(String username, String password) {
 4        System.out.println("-------UserManagerImpl.addUser()----------");
 5    }

 6
 7    public void deleteUser(int id) {
 8        System.out.println("-------UserManagerImpl.deleteUser()----------");
 9    }

10
11    public String findUserById(int id) {
12        System.out.println("-------UserManagerImpl.findUserById()----------");
13        return null;
14    }

15
16    public void modifyUser(int id, String username, String password) {
17        System.out.println("-------UserManagerImpl.modifyUser()----------");
18    }

19}


4、spring bean
 1<beans xmlns="http://www.springframework.org/schema/beans"
 2         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3         xmlns:aop="http://www.springframework.org/schema/aop"
 4         xmlns:tx="http://www.springframework.org/schema/tx"
 5         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 6           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
 7           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 8    <aop:aspectj-autoproxy/>
 9    <bean id="securityHandler" class="com.bjsxt.spring.SecurityHandler"/>           
10    <bean id="userManager" class="com.bjsxt.spring.UserManagerImpl"/>
11</beans>

三、使用xml配置方式
       业务接口和业务接口实现同上面例子,需要改变的地方有两处:
       1、切面Aspect
      
1public class SecurityHandler {
2    
3    private void checkSecurity() {
4        System.out.println("----------checkSecurity()---------------");
5    }

6}

     2、applicationContext.xml需要定义切面、切入点和通知
    
 1<beans xmlns="http://www.springframework.org/schema/beans"
 2         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3         xmlns:aop="http://www.springframework.org/schema/aop"
 4         xmlns:tx="http://www.springframework.org/schema/tx"
 5         xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 6           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
 7           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
 8    
 9    <bean id="securityHandler" class="com.bjsxt.spring.SecurityHandler"/>           
10    
11    <bean id="userManager" class="com.bjsxt.spring.UserManagerImpl"/>
12    
13    <aop:config>
14        <!-- 定义安全管理的方面 -->
15        <aop:aspect id="security" ref="securityHandler">
16            <!-- 定义切入点 -->
17            <aop:pointcut id="allAddMethod" expression="execution(* com.bjsxt.spring.UserManagerImpl.add*(..)))"/>
18            <!-- 定义通知:before -->
19            <aop:before method="checkSecurity" pointcut-ref="allAddMethod"/>
20        </aop:aspect>
21    </aop:config>    
22</beans>

          

        Aspect默认情况下不用实现接口,但对于目标对象(UserManagerImpl.java),在默认情况下必须实现接口
        如果没有实现接口必须引入CGLIB库

        我们可以通过Advice中添加一个JoinPoint参数,这个值会由spring自动传入,从JoinPoint中可以取得参数值、方法名等等
 

 1public class SecurityHandler {
 2    
 3    private void checkSecurity(JoinPoint joinPoint) {
 4        Object[] args = joinPoint.getArgs();
 5        for (int i=0; i<args.length; i++{
 6            System.out.println(args[i]);
 7        }

 8        
 9        System.out.println(joinPoint.getSignature().getName());
10        System.out.println("----------checkSecurity()---------------");
11    }

12}

         结果显示:
1张三
2123
3addUser
4----------checkSecurity()---------------
5-------UserManagerImpl.addUser()----------
       

只有注册用户登录后才能发表评论。


网站导航: