Spring 2.5 AOP Schema编程小解

VN:F [1.9.10_1130]
Rating: 0.0/5 (0 votes cast)

AOP是已经是蔓延了好几年的话题,不过因为没有标准化的平台以及工具的缺乏,一直没有很好的推广。这里所用的AOP实现主要是Spring对AspectJ的封装。感谢Spring的出色贡献,我们甚至都不用知道什么是AspectJ就可以使用AOP概念进行程序设计和实现了。

AOP编程模型

通常情况下,程序中有很多公共的部分,比如事务控制,比如LOG记录。他们遍布程序各处,使代码凌乱不堪难以维护。AOP是对OOP一个很好的补充。OOP很好的描述了业务模型中各个组件的交互方式,但是对于系统组件的装配与互操作,却鲜有明确的定义。

下面就是这样的一个应用场景,对于一个业务方法,比如queryUserInfo我们都需要事务控制,日志记录。

从业务方法角度看AOP

AOP  Example 1

在每一次调用业务方法时,AOP框架会使用around方式调用装配给业务方法的adviser..(可能更好理解的方式是类似 beforeMethod, afterMethod…)。

从Adviser看AOP

image

一个Adviser可能被装配给多个业务类的多个方法,通过不同的操作模型完成相关任务。

Spring 2.5 与AOP实现

下面通过一个非常简单的例子来说明Spring中AOP的Schema配置实现方式。

在此之前,应当对Spring 2.5 的Schema机制以及AOP AspectJ编程的一般概念有所了解。

请先阅读

下面是AOP的配置spring bean xml 文件


http://www.springframework.org/schema/beans" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
	
		
		
			
			
			
			
			
			
			
			
		
	
	
	
	

	
		
		
		
		
			
		
	

	
	
	


下面是 org.ave7.ws.aop.SystemMonitor 类的实现代码

package org.ave7.ws.aop;

import org.aspectj.lang.ProceedingJoinPoint;

import org.apache.commons.collections.LRUMap;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.apache.commons.lang.time.DurationFormatUtils;
import org.apache.commons.lang.time.StopWatch;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class SystemMonitor {

    private static final LRUMap logMap = new LRUMap(100);

    // 参数call包含了被调用方法的相关信息,请参考ApectJ网站
    public Object profileMethod(ProceedingJoinPoint call) throws Throwable {
        Log log = obtainLogger(call.getTarget().getClass());
        if (log.isDebugEnabled()) {
            log.debug("call " + call.getSignature().toLongString());
            log.debug("with para: "
                    + ReflectionToStringBuilder.toString(call.getArgs(),
                            ToStringStyle.MULTI_LINE_STYLE, true));

            StopWatch watch = new StopWatch();

            watch.start();

            try {
                Object rt = call.proceed();

                log.debug("return : "
                        + ReflectionToStringBuilder.toString(rt,
                                ToStringStyle.MULTI_LINE_STYLE, true));
                return rt;
            } catch (Throwable e) {
                log.warn("exception: " + e.getMessage(), e);
                throw e;

            } finally {
                watch.stop();
                log.debug("executing time: "
                        + DurationFormatUtils.formatDuration(watch.getTime(),
                                "m:s.S"));

            }
        } else {
            return call.proceed();
        }

    }

    private Log obtainLogger(Class clazz) {

        Log log = (Log) logMap.get(clazz);
        if (null == log) {
            log = LogFactory.getLog(clazz);
            logMap.put(clazz, log);
        }
        return log;
    }

}

您可能有兴趣的文章:

VN:F [1.9.10_1130]
Rating: 0.0/5 (0 votes cast)
Creative Commons License
This work, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.

One comment

  • 2008/02/22 - 3:00 PM | Permalink

    后悔了阿,后悔了

    既然来了,踩个脚印再走

    VA:F [1.9.10_1130]
    Rating: 0 (from 0 votes)
  • Leave a Reply

    Your email address will not be published. Required fields are marked *

    *

    You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>