【问题标题】:Spring AOP aspects ruined the contextSpring AOP 方面破坏了上下文
【发布时间】:2013-01-15 10:33:32
【问题描述】:

我正面临一个非常奇怪的麻烦。我在我的应用程序中使用注释驱动的 AspectJ。当我尝试继续我的方法时,我在自动装配的字段上收到空指针。 (在服务类中,我在拦截器中调用了哪些方法)。在使用 AspectJ 之前,spring 上下文工作得很好。我正在提供我的代码,也许我只是没有看到那个小错误:(花了太多时间找到它。:(

Aspect 类如下:

@Aspect
@Component
public class SomeInterceptor{

private static final Logger LOGGER = LoggerFactory.getLogger(SomeInterceptor.class);

@Autowired
@Qualifier("webServiceResponseFactory")
protected WebServiceResponseFactory responseFactory;

@Autowired
@Qualifier("configBean")
protected ConfigBean configBean;

public SomeServiceInterceptor () {
    LOGGER.info("Some service interceptor was created");
}

@Around("execution(public * pathToMyClassIsCorrect.*(..))")
public Object invoke(ProceedingJoinPoint pjp) throws Throwable {
    String securityTokenForMethod = pjp.getArgs()[0].toString();
    if (securityTokenForMethod != null) {
        LOGGER.info("Proceeding the securityTokenCheck before calling method "
                + pjp.getSignature().getName());
        if (validateAccessToken(securityTokenForMethod)) {
            return responseFactory
                    .buildFailedResponse("securityAccessToken is invalid for this request");
        }
    } else {
        throw new Throwable("There was an exception before calling method "
                + pjp.getSignature().getName());
    }

    try {
        LOGGER.info("Calling method " + pjp.getSignature().getName());
        Object methodToInvoke = pjp.proceed();
        LOGGER.info("Method " + pjp.getSignature().getName()
                + " was called successfully");
        return methodToInvoke;
    } catch (Throwable e) {
        LOGGER.info("Method " + pjp.getSignature().getName() + "threw an exception. ");
        boolean verboseError = Boolean.parseBoolean(pjp.getArgs()[1].toString());

        return responseFactory.buildErrorResponse(e, verboseError);
    }
}

}

我的 app-context.xml 包含并启用了所有组件扫描包。

非常感谢任何帮助。

编辑

另外,在调用之后我收到这样的错误:

SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container

编辑 2.0:

刚刚尝试在没有方面的情况下启动服务,工作正常。所以问题确实是由拦截服务方法的方面引起的。 :\

编辑 3.0:

我在构造函数中添加了一个记录器。所以,正如我所见,甚至没有创建对象。不知道是什么原因。

编辑 4.0: AspectJ 配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE aspectj PUBLIC
    "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
<weaver options="-verbose -showWeaveInfo -debug">
    <!-- only weave classes in our application-specific packages -->
    <include within="com.store.*"/>
    <include within="com.store.services.*"/>
</weaver>
<aspects>
    <!-- weave in just this aspect -->
    <aspect name="com.store.services.StoreServiceAspect"/>
</aspects>
</aspectj>

<weaver options="-verbose">
<include within="javax.*" />
<include within="org.aspectj.*" />
<include
    within="(!@NoWeave com.store.services.*) AND com.bsro.storewebsrv.services.*" />

<dump within="com.store.services.*" />
</weaver>

【问题讨论】:

  • 你使用 AspectJ 还是 AspectJ 风格的 Spring AOP?有很大的不同!
  • 我翻遍了那个文档:(
  • 仍然,您的问题标题和第二句话相互矛盾。它是哪一个:Spring AOP 还是 AspectJ?
  • 是 AspectJ,是的。我的错。太累了:(

标签: java spring aop aspectj


【解决方案1】:

您的错误处理代码很容易受到攻击:

LOGGER.info("Method " + pjp.getSignature().getName() + "threw an exception. ");
boolean verboseError = Boolean.parseBoolean(pjp.getArgs()[1].toString());

有很多机会可以掩盖您刚刚捕获的新异常。使异常处理程序无懈可击:不要解析任何内容,也不要通过调用可能为 null 的值的方法将自己暴露给 NPE。

【讨论】:

  • 好的。谢谢,刚刚修好了。但没有变化。
【解决方案2】:

我基于您的最后评论,这是 AspectJ 方面。

@Autowired 不适用于 AspectJ 方面。解决方法是使用工厂方法aspectOf 以这种方式注入您在方面所需的内容:

<bean class="SomeInterceptor" factory-method="aspectOf">
  <property name="webServiceResponseFactory" ref="..."/>
</bean>

【讨论】:

  • 刚刚得到“找不到匹配的工厂方法:工厂方法'aspectOf'错误。”
  • 好的,那么您的 AspectJ 设置中出现了问题,因为 AspectJ 编译器将 aspectOfhasAspect 方法注入到了方面。能否请您多分享一些与方面相关的配置
  • 谢谢,所以您基本上使用了正确的加载时间编织 - 如果可以,请显示您如何设置 ltw 的配置 - 仪器 jar 等,只是为了确保它设置正确
  • aop.xml 已更新。另外,我的上下文包含
  • 你有“-verbose -showWeaveInfo -debug”的编织器选项应该显示哪些类正在被正确编织 - 你能确认你看到相关的类正在被编织。此外,@Component 注释应该从方面中删除(不应该有任何副作用,但以防万一)。我假设您也使用-javaagent: 启动您的jvm?
【解决方案3】:

找到了解决办法。问题是ltw 无法正常工作,因为Tomcat 的应用程序上下文中缺少“Loader”。因此,按照 Spring 中的 8.8.3 参考指南,几乎修复了它。由于上述原因,未找到“aspectOf”。每当编织失败时都会引发此错误。此外,由于编织错误,自动装配的字段变为空。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2015-02-26
    • 2011-09-20
    • 2013-01-05
    相关资源
    最近更新 更多