首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spring Aspect的监视方法

使用Spring Aspect的监视方法
EN

Stack Overflow用户
提问于 2019-05-23 23:30:15
回答 1查看 341关注 0票数 2

我想实现用于日志记录的Spring方面。我尝试了这个实现:

日志记录方面:

代码语言:javascript
复制
    import org.apache.commons.lang.builder.ReflectionToStringBuilder;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    import javax.servlet.http.HttpServletRequest;
    import java.util.Arrays;
    import java.util.Enumeration;

    @Aspect
    @Component
    public class LoggingAspect {

        private static final String CONTROLLER_EXPRESION = "within(@org.springframework.stereotype.Controller *) && execution(* *.*(..))";
        private static final Logger log = LoggerFactory.getLogger(LoggingAspect.class);

        /**
         * Before -> Any resource annotated with @Controller annotation and all method
         * and function taking HttpServletRequest as first parameter.
         *
         * @param joinPoint
         * @param request
         */
        @Before(CONTROLLER_EXPRESION)
        public void logBefore(JoinPoint joinPoint, HttpServletRequest request) {

            log.debug("Entering in Method : {}", joinPoint.getSignature().getName());
            log.debug("Class Name :  {}", joinPoint.getSignature().getDeclaringTypeName());
            log.debug("Arguments :  {}", Arrays.toString(joinPoint.getArgs()));
            log.debug("Target class : {}", joinPoint.getTarget().getClass().getName());

            if (null != request) {
                log.debug("Start Header Section of request ");
                log.debug("Method Type : {}", request.getMethod());
                Enumeration headerNames = request.getHeaderNames();
                while (headerNames.hasMoreElements()) {
                    String headerName = headerNames.nextElement().toString();
                    String headerValue = request.getHeader(headerName);
                    log.debug("Header Name: {} Header Value : {}", headerName, headerValue);
                }
                log.debug("Request Path info : {}", request.getServletPath());
                log.debug("End Header Section of request ");
            }
        }

        /**
         * After -> All method within resource annotated with @Controller annotation.
         *
         * @param joinPoint
         * @param result
         */
        @AfterReturning(pointcut = CONTROLLER_EXPRESION, returning = "result")
        public void logAfter(JoinPoint joinPoint, Object result) {
            String returnValue = this.getValue(result);
            log.debug("Method Return value : {}", returnValue);
        }

        /**
         * After -> Any method within resource annotated with @Controller annotation and throws an exception ...Log it 
         * @param joinPoint
         * @param exception
         */
        @AfterThrowing(pointcut = CONTROLLER_EXPRESION, throwing = "exception")
        public void logAfterThrowing(JoinPoint joinPoint, Throwable exception) {
            log.error("An exception has been thrown in {} {}", joinPoint.getSignature().getName(), " ()");
            log.error("Cause : {}", exception.getCause());
        }

        /**
         * Around -> Any method within resource annotated with @Controller annotation. 
         * @param joinPoint
         * @return
         * @throws Throwable
         */
        @Around(CONTROLLER_EXPRESION)
        public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {

            long start = System.currentTimeMillis();
            try {
                String className = joinPoint.getSignature().getDeclaringTypeName();
                String methodName = joinPoint.getSignature().getName();
                Object result = joinPoint.proceed();
                long elapsedTime = System.currentTimeMillis() - start;
                log.debug("Method {}.{} () execution time :  {} ms", className, methodName, elapsedTime);

                return result;
            } catch (IllegalArgumentException e) {
                log.error("Illegal argument {} in {}()", Arrays.toString(joinPoint.getArgs()), joinPoint.getSignature().getName());
                throw e;
            }
        }

        private String getValue(Object result) {
            String returnValue = null;
            if (null != result) {
                if (result.toString().endsWith("@" + Integer.toHexString(result.hashCode()))) {
                    returnValue = ReflectionToStringBuilder.toString(result);
                } else {
                    returnValue = result.toString();
                }
            }
            return returnValue;
        }
    }

但是当我在应用服务器上部署代码时,我得到了这个错误堆栈:

代码语言:javascript
复制
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration': Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: error at ::0 formal unbound in pointcut 

我想要监视的控制器位于org.rest.api.server.controller.Homecontroller - Java method handle下。我是否需要指定确切的路径,或者我遗漏了其他内容?

EN

回答 1

Stack Overflow用户

发布于 2019-05-24 07:19:29

您的问题是由于logBefore中的额外参数HttpServletRequest;方面不能绑定到该参数。如果需要连接点的参数,最好在方面中检查它。因此,您的logBefore方法应该从以下更改:

代码语言:javascript
复制
    @Before(CONTROLLER_EXPRESION)
    public void logBefore(JoinPoint joinPoint, HttpServletRequest request) {

        // ASPECT LOGIC
        // ...
    }

要这样做:

代码语言:javascript
复制
    @Before(CONTROLLER_EXPRESION)
    public void logBefore(JoinPoint joinPoint) {
        HttpServletRequest request = (HttpServletRequest)joinPoint.getArgs()[0];

        // ASPECT LOGIC
        // ...
    }

希望这能有所帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56278581

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档