一个简单的例子实现自己的AOP

2018-06-15 13:36:36 浏览数 (1)

AOP是Aspect Oriented Programming的缩写,意思是面向切面编程,与OOP(Object Oriented Programming)面向对象编程对等,都是一种编程思想。

从OOP角度分析,我们关注业务的处理逻辑,是属于纵向的行为,从AOP角度分析,我们关注对象行为发生时的问题,是属于横向的行为。

AOP 作用:

1 监控函数的调用

2 捕获异常发生

实际应用在:事务、安全、日志等横切关注。

下面是aop打印service层的方法日志为例:

代码语言:javascript复制
/**
 * @功能描述: Service层日志/异常切面类
 */
@Component
@Aspect
public class ApiServiceAspect {

    private final Logger logger = Logger.getLogger(this.getClass());

    /**
     * 切面
     */
    private final String POINT_CUT = 
        "execution(* com.demo.bigdata.service.*.*.*(..))";

    @Pointcut(POINT_CUT)
    private void pointcut(){}

    @Before(value = POINT_CUT)
    public void before(JoinPoint joinPoint) {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        StringBuilder log = new StringBuilder();
        log.append("before: ")
                .append(className)
                .append("@")
                .append(methodName)
                .append(" , params: ");
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            log.append(JSONObject.toJSONString(arg)   ", ");
        }
        logger.info(log.toString());
    }

    @AfterReturning(value = "pointcut()", returning = "returnObj")
    public void afterReturn(Object returnObj) {
        String result = JSONObject.toJSONString(returnObj);
        logger.info("afterReturning: " result);
    }

    @AfterThrowing(value = POINT_CUT, throwing = "e")
    public void afterThrowing(Throwable e) {
        logger.error("afterThrowing: " e.getMessage(), e);
    }

    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) 
        throws Throwable {
        Long begin = System.currentTimeMillis();
        StringBuilder log = new StringBuilder("around: ");
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (Exception e) {
            logger.error(log   e.getMessage(), e);
        }
        Long end = System.currentTimeMillis();
        log.append(" 执行时间: ")
                .append(end-begin)
                .append("ms");
        return result;
    }

} 

配置文件使其生效

<context:component-scan base-package="com.demo.bigdata" />

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

如果使用了spring mvc后,如果把<aop:aspectj-autoproxy proxy-target-class="true"/>放在application.xml文件中可能会aop无效,最好把它放在dispatcher-servlet.xml文件中。

0 人点赞