Spring AOP 学习笔记-Springle 二代

阅读更多

Spring AOP 二代

Spring AOP 第一代中, AOP Advice 必须实现特定接口,而配置设置依赖于 XML 的繁琐设置。在 Spring2.0 之后,对于 AOP 功能的实现与设置新增了两种方法:一种是基于 XML Schema 的设置;一种是基于 Annotation 的支持。两种方式对于 AOP 在使用上的简化都有极大地帮助。而且 Advice 不用再实现任何其他特定的接口。

基于XML Schema的前置通知

在这里以实际的例子说明 Spring2.x AOP 的实现和设置上的改变,现在 LogBeforeAdvice 不需要实现 MethodBeforeAdvice ,改写后的程序如下。

 

public class LogBeforeAdvice {
    public void before(JoinPoint joinPoint) {
                                                                                                                System.out.println(joinPoint.getSignature().getName()+",start.............LogBeforeAdvice");
    }
}

在程序代码中, before() 方法为任意取的名称,它可以接受 JoinPoint 实例,也可以省略。可以使用 JoinPoint getTarget() 方法取得目标对象,使用 getArgs() 取得调用的方法参数、使用 getSinature() 方法取得 Pointcut 签名等信息。在 Spring2.x 任何一个 Advice 的方法实现都可以自行决定是否接受 JoinPoint 实例。

 

       
           
           
       

透过配置文件可以看到,首先不再需要明确声明使用 ProxyFactoryBean ,所有的 AOP 配置都是在 < aop:config > 标签中设置的; < aop:aspect > 标签定义 Aspect 的实现,也就是 Advice Pointcut 结合。

测试程序如下面所示:

public class AopTest {
    public static void main(String[] args) {
       BeanFactory factory = new ClassPathXmlApplicationContext(
              "applicationContext.xml");
       IHello bean = (IHello) factory.getBean("IHello");
       bean.hello1("AOP1");
       bean.hello2("AOP2");
    }
}

 

 

测试结果如下:

hello1,start.............LogBeforeAdvice
hello1,AOP1
hello2,start.............LogBeforeAdvice
hello2,AOP2

     基于Annotation的前置通知

 

Spring2.0 以后,还可以通过 Annotation 来设置 AOP Advice ,在 XML 的设置上可以更加简化,这里改写 LogBeforeAdvice

 

@Aspect
public class LogBeforeAdvice {
    @Pointcut("execution(* com.edu.cug.IHello.*(..)) ")
    public void anymethod(){}
    @Before("anymethod()")
    public void before(JoinPoint joinPoint) {
       System.out.println(joinPoint.getSignature().getName()
              + ",start.............LogBeforeAdvice");
    }
}

配置文件修改如下:

 

 

测试程序如下:

 

public class AopTest {
    public static void main(String[] args) {
       BeanFactory factory = new ClassPathXmlApplicationContext(
              "applicationContext.xml");
       IHello bean = (IHello) factory.getBean("IHello");
       bean.hello1("AOP1");
       bean.hello2("AOP2");
    }
}

运行结果如下:

 

hello1,start.............LogBeforeAdvice
hello1,AOP1
hello2,start.............LogBeforeAdvice
hello2,AOP2

可以看到,基于 Annotation AOP 设置方式,在 XML 上几乎不用设置,只要实例化 Advice 与你的目标对象,接着一切就让 Spring 自动取得 Annotation 信息,进行代理对象建立,无须再做任何的设置。这个范例的执行结果和上一个范例是相同的。

Spring的Pointcut定义

 

Spring2.x 中要声明 Pointcut ,主要包括两个部分: Pointcut 表达式 (expression) Pointcut 签名 (signature) 。首先来看 Pointcut 表达式,在 Spring 中, execution 表示式会是最常用的 Pointcut 表示式,它的语法组成格式如下所示:

Execution (modifiers –patterns?
ret-type-pattern
declaring-type-pattern?
name-pattern (param-pattern)
throws-pattern?
)

它们分别表示存取修饰匹配 (modifiers –patterns) 、返回值类型匹配 (ret-type-pattern

) 、类限定名匹配 (declaring-type-pattern) 、方法名称匹配 ( 参数类型匹配 ) 、异常类型匹配 (throws-pattern) 、有问号的部分,表示可以省略不声明。

         Spring2.x 中,结合 @Pointcut Annotation 定义方式,可以让 Pointcut 在定义上更加容易,定义包含两个部分: Pointcut 表示式与 Pointcut 签名 (signature)

         Pointcut 定义是,还可以使用 && || ! 运算。

      使用 Spring2.x 的新特性实现 AOP 更加简单、快捷,所以使用 Spring2.x 或更高的版本能缩短开发周期,性能方面丝毫不逊色以前的 AOP 支持。

你可能感兴趣的:(AOP,Spring,Bean,XML)