Spring2.0 AOP 之Before,After,Thrown,Around Advice(一)

在Spring 2.0里要使用AOP的话,大大的简化了,不管是程序书写还是xml 配置,下面我说一下我的学习和使用过程:

 

我以日志功能为例子,假如我们写了一个method,然后我们想在这个method执行做一件事,执行后做一件事,或是发生异常时怎么样,有的人在想那还不简单,我直接在在这个方法里加上不就行了,但是再想想当一个项目做大后,用这种方法会给以后的维护带来很多麻烦,因为你已经把这些本不属于程序逻辑的事情也耦合到里面了,如果加的地方多的话,以后麻烦可就大了,而利用Spring AOP  想加这个日志功能就简单了,完全与程序逻辑解耦,以后想添改什么的,单独去处理就方便好多了。在Spring 2.0里不再需要去实现好多的接口去做这些事情,配置也很简单了,

 

讲解背景如下:

我有一个接口 IHello

 

public interface IHello {
    public void hello(String name);
}

 

有一个实现类HelloSpeaker

 

public class HelloSpeaker implements IHello {

    public void hello(String name) {
        System.out.println("Hello,"+name);
    }

}

 

 1.Before Advice

  现在我想在hello方法执行前加个log怎么做呢,这里我们要加个class 叫 LogAspect

 

 专门去处理log

 

 public class LogAspect {
   
    private Logger logger=Logger.getLogger(this.getClass().getName());

 

    public void before(JoinPoint jointPoint) {
        logger.log(Level.INFO, "method starts..."
                + jointPoint.getSignature().getDeclaringTypeName() + "."
                + jointPoint.getSignature().getName());
    }

}

 

 然后建个spring基于xml schema的文件

 

 

 

再写个TestClass

 

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("beans-config.xml");
        IHello helloSpeaker=(IHello)context.getBean("helloSpeaker");
        helloSpeaker.hello("Jack");
    }

 

 现在可运行了,但是运行前确保加上asm-*.jar 2.2.1或2.2.2 version ,asm-attrs-2.2.2.jar, asm-commons.jar我的是2.2.的

 

 aspectjweaver-1.5.3.jar     commons-logging-1.0.4.jar

 

spring所需的就不用说了。然后运行结果如下:

 

2009-2-23 15:38:59 LogAspect before
信息: method starts...IHello.hello

Hello,Jack

 

2.After Advice

 

有两种:After和Afterreturning(可以设置目标方法调用的传回值)

 

现在原LogAspec里加个方法:

 

    public void after(JoinPoint jointPoint){
        logger.log(Level.INFO, "method ends..."
                + jointPoint.getSignature().getDeclaringTypeName() + "."
                + jointPoint.getSignature().getName());
    }

beans-config.xml里加上:

 

<aop:after pointcut-ref="logHello" method="after"/>

 

运行后成了:

 

2009-2-23 15:42:27 LogAspect before
信息: method starts...IHello.hello
2009-2-23 15:42:27 LogAspect after
信息: method ends...IHello.hello
Hello,Jack

 

有人说不对啊,这哪里是前和后啊,这里要说明,log是由另一个线程进行操作的,并不影响原有程序的流程。

 

 

3.After Throwing Advice:

 

现在原LogAspec里加个方法:

 

    public void afterThrowing(JoinPoint jointPoint,Throwable throwable){
        logger.log(Level.INFO, "Logging that a " + throwable +
                "/nException was thrown in..."+
                jointPoint.getSignature().getDeclaringTypeName() + "."
                + jointPoint.getSignature().getName());
    }

 

配置文件:

 

 <aop:after-throwing pointcut-ref="logHello" throwing="throwable" method="afterThrowing"/>

 

现在故意把hello里修改一下让其引发异常:

 

System.out.println("Hello,"+Integer.parseInt(name));//Testing Exception

 

运行结果如下:

 

2009-2-23 15:46:30 LogAspect before
信息: method starts...IHello.hello
2009-2-23 15:46:30 LogAspect after
信息: method ends...IHello.hello
2009-2-23 15:46:30 LogAspect afterThrowing
信息: Logging that a java.lang.NumberFormatException: For input string: "Jack"
Exception was thrown in...IHello.hello
java.lang.NumberFormatException: For input string: "Jack"

 

 

4. Around Advice :

 

这个可以实现在前和后加上log

 

同样增加一个方法:

 

    public Object invoke(ProceedingJoinPoint jointPoint) throws Throwable{
       
        logger.log(Level.INFO, "method starts..."
                + jointPoint.getSignature().getDeclaringTypeName() + "."
                + jointPoint.getSignature().getName());
       
        Object retVal=jointPoint.proceed();
       
        logger.log(Level.INFO, "method ends..."
                + jointPoint.getSignature().getDeclaringTypeName() + "."
                + jointPoint.getSignature().getName());

       
        return retVal;
    }

 

 

配置xml文件:

 

<aop:around pointcut-ref="logHello" method="invoke"/>

 

运行结果如下:

 

2009-2-23 15:49:04 LogAspect invoke
信息: method starts...IHello.hello
2009-2-23 15:49:04 LogAspect afterThrowing
信息: Logging that a java.lang.NumberFormatException: For input string: "Jack"
Exception was thrown in...IHello.hello
java.lang.NumberFormatException: For input string: "Jack"

 

大家一看就会发现啊!后面的log没有执行,这里可以告诉我们用Around实现前和后加入log和分别用Before和After的区别之一了。

 

 

 未完待续

 

[转载请注明出处]

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值