Spring AOP 学习笔记-Springle 二代

Spring AOP 二代

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

基于XML Schema的前置通知

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

 

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

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

 <bean id="logBeforeAdvice" class="com.edu.cug.LogBeforeAdvice"/>
<aop:config>
       <aop:aspect id="logBeforeAspect" ref="logBeforeAdvice">
           <aop:pointcut id="LogbeforePointcut" expression="execution(* hello*(..))"/>
           <aop:before pointcut-ref="LogbeforePointcut" method="before"/>
       </aop:aspect>
</aop:config>

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

测试程序如下面所示:

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 来设置 AOPAdvice ,在 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");
    }
}

配置文件修改如下:

 <bean id="IHello" class="com.edu.cug.IHelloImpl"></bean>
<bean id="logBeforeAdvice" class="com.edu.cug.LogBeforeAdvice"></bean>
<aop:aspectj-autoproxy/>

 

测试程序如下:

 

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

可以看到,基于 AnnotationAOP 设置方式,在 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 中,结合 @PointcutAnnotation 定义方式,可以让 Pointcut 在定义上更加容易,定义包含两个部分: Pointcut 表示式与 Pointcut 签名 (signature)

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值