【问题标题】:java.lang.IllegalArgumentException: error at ::0 can't find referenced pointcutjava.lang.IllegalArgumentException: ::0 处的错误找不到引用的切入点
【发布时间】:2016-01-28 02:19:24
【问题描述】:

我对 Spring AOP 真的很陌生。在我的应用程序中,我配置了 HiddenHttpMethodFilter,它将方法参数转换为 HTTP 方法,并使 Spring 能够处理其他 HTTP 方法,例如 DELETEPUT 等,包括 GETPOST

有时需要禁用此功能,尤其是在处理多部分请求时。为了在特定请求时禁用它(关于 mulripart),我使用了以下代码。

package resolver;

import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.util.Assert;
import org.springframework.web.multipart.MultipartResolver;

/**
 * Disables the spring multipart resolver for specific client requests and
 * therefore keeps the request intact so that controllers can process it in
 * whatever way they wish. This behaviour is triggered by a particular GET
 * parameter in the client request so it is configurable.
 * @see MultipartResolver
 */
@Aspect
public final class MultipartResolverDisablingAspect
{
    /**
     * GET parameter which, if present in request, enables advice.
     */
    private static final String DISABLING_HTTP_REQUEST_PARAMETER_KEY = "_multipartResolverDisable";

    private static boolean disablingParameterExists(final HttpServletRequest request) 
    {
        Assert.notNull(request);
        return request.getParameter(DISABLING_HTTP_REQUEST_PARAMETER_KEY) != null;
    }

    /**
     * If above GET parameter exists in request then prompt the spring multipart
     * resolver to always tell spring that request is not of type multipart.
     * Spring then does not process the request any further.
     * @param pjp
     * @param request
     * @return
     * @throws Throwable
     */
    @Around("isMultipartOperation() && args(request)")
    public Object disableIsMultipartOperation(final ProceedingJoinPoint pjp, final HttpServletRequest request) throws Throwable 
    {

        Assert.notNull(pjp);
        Assert.notNull(request);

        if (disablingParameterExists(request)) 
        {
            return Boolean.FALSE;
        }

        return pjp.proceed();
    }

    /**
     * Applies to any implementation of {@linkplain MultipartResolver}
     */
    @SuppressWarnings("unused")
    @Pointcut("execution(public boolean " + "org.springframework.web.multipart.MultipartResolver." + "isMultipart(javax.servlet.http.HttpServletRequest))")
    private void isMultipartOperation() {}
}

并且在application-context.xml 文件中,需要以下xml。

<aop:aspectj-autoproxy proxy-target-class="false" />
<bean class="resolver.MultipartResolverDisablingAspect" /> <!--Registers the above bean (class)-->

此代码取自 this 部分下的文章 - MULTIPART RESOLVER DISBLING ASPECT。

GET 参数multipartResolverDisable=1 用作查询字符串如上面的代码指定 时,这意味着通过HiddenHttpMethodFilter 禁用多部分处理,以便可以使用commons fileupload像往常一样(当multipartResolverDisable=1 作为查询字符串提供时)


实际问题仍然不在图片中。此方法之前在以下环境中正常工作(使用 NetBeans 6.9.1)。

  • 春季 3.2.0
  • Apache Tomcat 6.0.26.6 与 Servlet API 2.5。

最近我用 Apache Tomcat 7.0.35 升级了 NetBeans 7.2.1,它具有 Servlet API 3.0。 Spring 版本与之前相同 - Spring 3.2.0。

通过此更新,上述方法导致以下异常。

Caused by: org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.springframework.transaction.config.internalTransactionAdvisor':
Cannot resolve reference to bean
'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0'
while setting bean property 'transactionAttributeSource'; nested
exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name
'org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#0':
Initialization of bean failed; nested exception is
**java.lang.IllegalArgumentException: error at ::0 can't find referenced
pointcut isMultipartOperation**

isMultipartOperation() 是上述类中的最后一个方法。

代码可能会有一点小改动,但我对 AOP 了解甚少,无法在这段好看的代码中找出这个异常的原因。

这个异常的原因是什么?它必须与 Servlet API 做些什么吗?

【问题讨论】:

    标签: spring aop spring-aop multipart pointcut


    【解决方案1】:

    我认为您应该将您的周围建议更改为

    @Around("isMultipartOperation(..) && args(request)")
    

    你的切入点注释

    @Pointcut("execution(* org.springframework.web.multipart.MultipartResolver.isMultipart(..)) && args(request)")
    

    以及切入点注释方法

    private void isMultipartOperation(HttpServletRequest request) {}
    

    从记忆中,我遇到了这个问题,我试图用一些建议包装一个切入点,并且该建议对切入点有不同数量的参数。在您的代码中,您似乎使用 @Around 来定位带有 args(request) 的切入点,但您的切入点方法没有这样的参数。

    【讨论】:

    • 您好,感谢您的回复。我已经完全按照您提到的方式进行了尝试,但不幸的是它没有任何区别。问题中提到的异常一直在抛出。看起来很简单,但我不确定为什么它不适用于更高版本的 Spring - 3.2.0,之前版本 3.0.2 就是这种情况。
    • 你在使用 Maven 吗?如果是这样,可能值得检查 dependency:tree 以查看某些相关 jar(例如 aspectj / aspectjweaver)版本是否已更改或已从必需更改为可选。您在使用 吗?也许将日志记录转为跟踪 log4j.logger.org.springframework.aop=TRACE 并查看启动以查看哪些与 aop 相关的更改正在应用于您的类以及它们与日志输出时的不同之处使用 3.0.2。
    • 我刚刚注意到,在我的一些工作aop(Spring 3.1.2)中,切入点被指定为@Pointcut(value = "execution(* a.b..*.*(..)) &amp;&amp; @annotation(myAnnotation)"),周围的建议为@Around("cachedMethod(myAnnotation)") public Object processCacheLookup(ProceedingJoinPoint pjp, MyAnnotation myAnnotation) throws Throwable { - 可能值得一试 - 再一次,不知道为什么它在一个 Spring 版本而不是另一个版本中工作。
    • 我的项目没有使用 Maven,因此没有 Mavan 依赖项。我尝试了@Pointcut(value="execution("* org.springframework.web.multipart.MultipartResolver." + "isMultipart(javax.servlet.http.HttpServletRequest))&amp;&amp; @annotation(request)") 和周围的建议@Around("isMultipartOperation(request)"),但异常并没有消失。
    • 在我的 spring-security.xml 文件中,这个切入点表达式 - execution(* dao.*.*(..)) 像 - &lt;global-method-security&gt; &lt;protect-pointcut expression="execution(* dao.*.*(..))" access="ROLE_ADMIN"/&gt; &lt;/global-method-security&gt; 一样正常工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多