当前位置: 首页 > 知识库问答 >
问题:

将请求范围对象注入@方面

易雅畅
2023-03-14

我有一个spring AOP方面类,它在每次调用服务时都会记录日志,我计划在日志中打印更多信息,这次每个请求都会有唯一的标识符,该标识符存储在请求范围的对象中,直到服务返回。我尝试将请求对象注入到@方面,但似乎效果不佳。

如果只有一个建议,它在我调用该服务时起作用,如果我添加更多建议,它会出错。(问题结束)

@Aspect
public class LoggingAspect {

    private Logger log = Logger.getLogger(getClass());

    @Autowired
    public RequestScopeObject params;

    @Pointcut("within(net.company.dao..*)")
    private void clDaoLayer() {

    }

    private String uniqueIdentifier(){
       String uid = "";

       if(this.params!=null && this.params.getId()!= null){
          uid = "ID:"+this.params.getId()+" ";
       }else{
          uid = "";
       }
       return uid;
   }

    @Around("clDaoLayer()")
    public Object clDaoLayerAdvice(ProceedingJoinPoint joinPoint)
            throws Throwable {
        String TAG = uniqueIdentifier();
        // gets the system property dynamically for debugging purpose.
        this.printObject = Boolean.parseBoolean(System.getProperty("printobject"));
        Date start = new Date();
        String methodInExcecuting = getSignature(joinPoint);
        log.debug(TAG+"calling method.." + methodInExcecuting
                + " with arguments : " + Arrays.toString(joinPoint.getArgs()));
        Object result = null;
        String slug = "";
        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            log.error(TAG+" Exception .." + methodInExcecuting, e);
            throw e;
        }
        try {
            if (printObject == true) {
                if (result == null) {
                    slug = " null ";
                } else if (result instanceof List) {
                    slug = ((List) result).toString() + "\n"
                            + ((List) result).size() + "";
                } else if (result.getClass().toString().indexOf("[L") >= 0) {// if
                                                                                // array
                                                                                // get
                                                                                // length
                    slug = ArrayUtils.toString(result) + ". "
                            + ArrayUtils.getLength(result);
                } else if (result != null) {
                    slug = result.toString() + ". 1 value ";
                }
                slug += "\nvalues/rows returned.";
            } else {
                slug = "";
            }
        } catch (Exception e) {
            log.debug(TAG+"Error getting slug..");
        }
        Date end = new Date();
        log.debug(TAG+" Time taken: "
                + (end.getTime() - start.getTime()) + " milliseconds."+"returning from " + methodInExcecuting + ". " + slug);
        return result;
    }

}

日志错误

java.lang.reflect.UndeclaredThrowableException
    at org.jboss.ws.core.server.ServiceEndpointInvoker.invoke(ServiceEndpointInvoker.java:228)
    at org.jboss.wsf.stack.jbws.RequestHandlerImpl.processRequest(RequestHandlerImpl.java:474)
    at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleRequest(RequestHandlerImpl.java:295)
    at org.jboss.wsf.stack.jbws.RequestHandlerImpl.doPost(RequestHandlerImpl.java:205)
    at org.jboss.wsf.stack.jbws.RequestHandlerImpl.handleHttpRequest(RequestHandlerImpl.java:131)
    at org.jboss.wsf.common.servlet.AbstractEndpointServlet.service(AbstractEndpointServlet.java:85)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
    at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
    at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.StackOverflowError
    at java.util.Date.<init>(Date.java:146)
    at net.LoggingAspect.restClientHelperAdvice(LoggingAspect.java:134)
    at sun.reflect.GeneratedMethodAccessor317.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:621)
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:610)
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:65)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:90)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy593.getId(Unknown Source)

共有2个答案

薛兴言
2023-03-14

我也有同样的问题。我的解决方案是将数据存储在请求范围的bean中,并从应用程序上下文中懒惰地获取该bean:

@Aspect
public class PerformanceMonitoringAspect implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    private boolean isRequestScopeAvailable() {
        return RequestContextHolder.getRequestAttributes() != null;
    }

    public Optional<QueryCounter> getQueryCounter() {
        if (isRequestScopeAvailable()) {
            return Optional.of(applicationContext.getBean(QueryCounter.class));
        }
    return Optional.empty();
    }

    @Before("@annotation(com.whatever.CountAsWriteQuery)")
    public void countAsWriteQueries() {
        getQueryCounter().ifPresent(QueryCounter::incrementWrite);
    }
}


@RequestScope
public class QueryCounter {
    public void incrementWrite(){
        ...
    }
}
章学义
2023-03-14

我使用了ThreadLocal的帮助来维护我要打印的信息。我使用静态变量来保存线程局部变量

public class WorkThreadLocal {

    public static ThreadLocal<String> id = new ThreadLocal<String>(){
        @Override
        protected String initialValue()
        {
            return "";
        }
    };

}

更新LogginAspect.java如下

@Aspect
public class LoggingAspect {

    private Logger log = Logger.getLogger(getClass());

    @Autowired
    public RequestScopeObject params;

    @Pointcut("within(net.company.dao..*)")
    private void clDaoLayer() {

    }

    private String uniqueIdentifier(){
       String uid = "";
       if (WorkThreadLocal.mwi != null) {
         uid = WorkThreadLocal.id.get() + " ";
       }
       return uid;
    }

    @Around("clDaoLayer()")
    public Object clDaoLayerAdvice(ProceedingJoinPoint joinPoint)
            throws Throwable {
        String TAG = uniqueIdentifier();
        // gets the system property dynamically for debugging purpose.
        this.printObject = Boolean.parseBoolean(System.getProperty("printobject"));
        Date start = new Date();
        String methodInExcecuting = getSignature(joinPoint);
        log.debug(TAG+"calling method.." + methodInExcecuting
                + " with arguments : " + Arrays.toString(joinPoint.getArgs()));
        Object result = null;
        String slug = "";
        try {
            result = joinPoint.proceed();
        } catch (Exception e) {
            log.error(TAG+" Exception .." + methodInExcecuting, e);
            throw e;
        }
        try {
            if (printObject == true) {
                if (result == null) {
                    slug = " null ";
                } else if (result instanceof List) {
                    slug = ((List) result).toString() + "\n"
                            + ((List) result).size() + "";
                } else if (result.getClass().toString().indexOf("[L") >= 0) {// if
                                                                                // array
                                                                                // get
                                                                                // length
                    slug = ArrayUtils.toString(result) + ". "
                            + ArrayUtils.getLength(result);
                } else if (result != null) {
                    slug = result.toString() + ". 1 value ";
                }
                slug += "\nvalues/rows returned.";
            } else {
                slug = "";
            }
        } catch (Exception e) {
            log.debug(TAG+"Error getting slug..");
        }
        Date end = new Date();
        log.debug(TAG+" Time taken: "
                + (end.getTime() - start.getTime()) + " milliseconds."+"returning from " + methodInExcecuting + ". " + slug);
        return result;
    }

}
 类似资料:
  • 我试图用jsf和CDI编写一个简单的登录表单。问题是当我注入我的SessionScoped bean时,它不像我期望的那样工作。这是我的豆子 这是我的控制器: 还有一个简单的Jsf表单,它调用login函数并显示LoginInfo类的计数器字段。 通过单击登录按钮和调试变量,我可以看到“lo”是这样的: lo={LoginInfo$Proxy$_$$_WeldClientProxy@16688}“

  • 我已经看了很多帖子,似乎没有什么能像我喜欢的那样工作。 我想将一个对象从一个过滤器注入到ContainerRequestContext属性中,然后在其他类中检索它。 这是我的过滤器: 下面是我想要访问ContainerRequestContext的类: 我的spring配置: 如果我将容器请求上下文注入到我的 Web 资源中,一切都按预期工作。但是,如果调用我的提供程序类容器请求上下文始终为空。

  • 问题内容: 我正在尝试在Spring中建立一个请求范围的bean。 我已经成功设置好了,所以每个请求创建一次bean。现在,它需要访问HttpServletRequest对象。 由于该bean是每个请求创建一次的,所以我认为容器可以轻松地将请求对象注入到我的bean中。我怎样才能做到这一点 ? 问题答案: 可以将请求范围的Bean与请求对象自动连接。

  • 本文解释了可以将RequestScoped Bean注入ApplicationScoped Bean中,并且客户机代理将在请求期间指向正确的实例:在CDI中,较短范围的Bean实例注入较大范围的Bean实例中-它是如何工作的? 当使用一个单独的生产者类进行额外处理并生成RequestScoped bean时,这是如何工作的?在部署到应用服务器时,由于不明确的依赖关系,我得到一个Deployment

  • 我得到的错误是: 我检查的内容: > 已启用批注处理,否则AnyService根本不会实例化 AnyBean不是最终的 请求作用域在AnyBean中与AspectJ代理(ScopedProxyMode.target_class)一起定义 存在EnableAspectJAutoproxy批注 类路径上有以下JAR: Web XML还包含RequestContextListener: 当我向org.s