Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用AspectJ样式的Spring AOP(@Around建议使用@Transactional webservice方法)的请求范围bean的空指针异常_Java_Spring_Service_Aop_Aspectj - Fatal编程技术网

Java 使用AspectJ样式的Spring AOP(@Around建议使用@Transactional webservice方法)的请求范围bean的空指针异常

Java 使用AspectJ样式的Spring AOP(@Around建议使用@Transactional webservice方法)的请求范围bean的空指针异常,java,spring,service,aop,aspectj,Java,Spring,Service,Aop,Aspectj,我使用的是Spring 3.1.0.RC1。我有一个基于apachecxf的web服务。我试图为每个@Transactional注释服务方法提供建议 我有一个方面和一些周围的建议。在该方法中,我将数据存储到一个请求范围的事务负载bean中。稍后,我在另一个单例作用域bean中从这个有效负载中请求uuid。结果是空指针异常 Caused by: java.lang.RuntimeException: java.lang.NullPointerException at com.spp.mui

我使用的是Spring 3.1.0.RC1。我有一个基于apachecxf的web服务。我试图为每个@Transactional注释服务方法提供建议

我有一个方面和一些周围的建议。在该方法中,我将数据存储到一个请求范围的事务负载bean中。稍后,我在另一个单例作用域bean中从这个有效负载中请求uuid。结果是空指针异常

Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at com.spp.mui.jaxws.service.virtual._0_1.VirtualWebService.postOfferSet(VirtualWebService.java:209)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
    at com.spp.mui.aop.tx.NewAgeTransactionLoggingAspect.logTransaction(NewAgeTransactionLoggingAspect.java:85)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    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:161)
    at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:80)
    at com.spp.mui.aop.ws.TraceWebServiceMethodAspect.invoke(TraceWebServiceMethodAspect.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    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 $Proxy95.postOfferSet(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:173)
    at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:89)
    ... 49 more
Caused by: java.lang.NullPointerException
    at com.spp.mui.jaxws.agent.WSResponseAgent.getResponse(WSResponseAgent.java:28)
    at com.spp.mui.jaxws.agent.WSResponseAgent.getResponse(WSResponseAgent.java:18)
    at com.spp.mui.jaxws.handler.offer.PostVirtualOffersHandler.handle(PostVirtualOffersHandler.java:58)
    at com.spp.mui.jaxws.service.virtual._0_1.VirtualWebService.postOfferSet(VirtualWebService.java:205)
    ... 88 more
那么堆栈跟踪中发生了什么

调用了一个web服务方法,即postOfferSet。该方法是由一个带有@Around切入点的方面建议的。该方法还带有@Transactional注释

更新我已经将原始配置更新为基于Java配置。无论是XML配置还是Java配置,我都遇到了相同的问题。我的Java配置是目前正在使用的配置,也是我需要帮助诊断的配置。请向下滚动并向前跳过以查看下面的Java配置。对于本帖的其他新手,请继续阅读

我的方面配置看起来有点像

 <aop:aspectj-autoproxy />

 <bean id="newAgeTxLoggingAspect" class="com.spp.mui.aop.tx.NewAgeTransactionLoggingAspect">
    <property name="transactionLogService" ref="txLogServiceEngine" />
    <property name="securable" ref="securityAgent" />
    <property name="loggableTransactionToken" ref="loggableTransactionToken" />
    <property name="logQuery" value="${newAgeTxLoggingAspect.logQuery}" />
    <property name="logReply" value="${newAgeTxLoggingAspect.logReply}" />
    <property name="logSubmit" value="${newAgeTxLoggingAspect.logSubmit}" />
    <property name="maxReplySize" value="${newAgeTxLoggingAspect.maxReplySize}" />
    <property name="maxRequestSize" value="${newAgeTxLoggingAspect.maxRequestSize}" />
    <property name="order" value="5" />
</bean>
希望我能提供足够的帮助你帮我调查为什么我会得到NPE

更新这里的Java配置和附加impl

AOP配置

@Configuration
@EnableAspectJAutoProxy
@Import(value = { LoggingConfig.class, AuthConfig.class })
public class AopConfig {

@Resource
private Environment env;

@Resource
private LoggingConfig loggingConfig;

@Resource
private AuthConfig authConfig;

/* Consult
 *   static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-applying-more-than-just-tx-advice
 *   and http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-ataspectj-advice-ordering
 */

@Bean
public NewAgeTransactionLoggingAspect txLoggingAspect() {
    NewAgeTransactionLoggingAspect aspect = new NewAgeTransactionLoggingAspect();
    aspect.setEnvironment(env);
    aspect.setLoggableTransactionToken(loggingConfig.loggableTxToken());
    aspect.setSecurable(authConfig.securable());
    aspect.setTransactionLogService(loggingConfig.txLogService());
    aspect.setLogQuery(Boolean.valueOf(env.getProperty("newAgeTxLoggingAspect.logQuery", Boolean.toString(true))));
    aspect.setLogReply(Boolean.valueOf(env.getProperty("newAgeTxLoggingAspect.logReply", Boolean.toString(true))));
    aspect.setLogSubmit(Boolean.valueOf(env.getProperty("newAgeTxLoggingAspect.logSubmit", Boolean.toString(true))));
    aspect.setMaxRequestSize(Integer.valueOf(env.getProperty("newAgeTxLoggingAspect.maxRequestSize", "100000000")));
    aspect.setMaxReplySize(Integer.valueOf(env.getProperty("newAgeTxLoggingAspect.maxReplySize", "100000000")));
    aspect.setOrder(Integer.valueOf(env.getProperty("newAgeTxLoggingAspect.order", "5")));
    return aspect;
}


}
下面是负责设置NewAgeTransactionLoggingService和LoggableTransactionToken的配置中的一个片段

@Bean
public TransactionLogService txLogService() {
    HibernateTransactionLogService service = new HibernateTransactionLogService();
    service.setLogParameters(Boolean.valueOf(Boolean.toString(true)));
    service.setTimeDispatcher(timeConfig.timeDispatcher());
    service.setSessionFactory(sessionFactory);
    return service;
}


/**
 * @return <p>Request scoped bean that allows LoggableTransaction instances to be created and accessed on a request.<br/>
 * Consult <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection">Bean Factory Scopes</a></p>
 */
@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public Token<LoggableTransaction> loggableTxToken() {
    // XXX Is this is the correct way to specify a request-scoped bean?
    LoggableTransactionToken token = new LoggableTransactionToken();
    return token;
}

所以,我不得不再次自己解决这个问题

基本要素:

1创建一个自定义ServletFilter,创建LoggabletTransaction并在那里设置令牌。我扩展了Spring的OncePerRequestFilter,并使用WebApplicationContextUtils在doFilterInternal方法中获取请求范围的bean

2在web.xml中注册此筛选器。还要确保注册Spring的RequestContextListener和ContextLoaderListener

3除了切入点参考,上面的方面实现保持不变。切入点现在引用web服务委托给的服务方法

这是最关键的。。。如果令牌没有实现接口,那么bean定义应该用@Scopevalue=request,proxyMode=ScopedProxyMode.TARGET_类修饰。在类路径上需要CGLib。我需要它来冬眠


后来一切都很顺利

请注意,web服务方法是双重建议的。我有两个方面:NewAgeTransactionLoggingAspect NATLA和TraceWebServiceMethodAspect TWSMA。我关心的是前者。另外,应用于方面的order属性是NATLA-5、TWSMA-2、@Transactional via tx:annotation-driven namespace-200。此后,我将TraceWebServiceMethodAspect拉出,因为我能够获得与Apache CXF的CXF:logging相同的功能性。
@Override
public ConfirmationType getResponse() {
    ConfirmationType response = new ConfirmationType();
    LoggableTransaction lt = token.getToken();
    response.setTransactionID(lt.getUuid());
    logger.debug(ReflectUtil.toString(lt));
    return response;
}
@Configuration
@EnableAspectJAutoProxy
@Import(value = { LoggingConfig.class, AuthConfig.class })
public class AopConfig {

@Resource
private Environment env;

@Resource
private LoggingConfig loggingConfig;

@Resource
private AuthConfig authConfig;

/* Consult
 *   static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-applying-more-than-just-tx-advice
 *   and http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/aop.html#aop-ataspectj-advice-ordering
 */

@Bean
public NewAgeTransactionLoggingAspect txLoggingAspect() {
    NewAgeTransactionLoggingAspect aspect = new NewAgeTransactionLoggingAspect();
    aspect.setEnvironment(env);
    aspect.setLoggableTransactionToken(loggingConfig.loggableTxToken());
    aspect.setSecurable(authConfig.securable());
    aspect.setTransactionLogService(loggingConfig.txLogService());
    aspect.setLogQuery(Boolean.valueOf(env.getProperty("newAgeTxLoggingAspect.logQuery", Boolean.toString(true))));
    aspect.setLogReply(Boolean.valueOf(env.getProperty("newAgeTxLoggingAspect.logReply", Boolean.toString(true))));
    aspect.setLogSubmit(Boolean.valueOf(env.getProperty("newAgeTxLoggingAspect.logSubmit", Boolean.toString(true))));
    aspect.setMaxRequestSize(Integer.valueOf(env.getProperty("newAgeTxLoggingAspect.maxRequestSize", "100000000")));
    aspect.setMaxReplySize(Integer.valueOf(env.getProperty("newAgeTxLoggingAspect.maxReplySize", "100000000")));
    aspect.setOrder(Integer.valueOf(env.getProperty("newAgeTxLoggingAspect.order", "5")));
    return aspect;
}


}
@Bean
public TransactionLogService txLogService() {
    HibernateTransactionLogService service = new HibernateTransactionLogService();
    service.setLogParameters(Boolean.valueOf(Boolean.toString(true)));
    service.setTimeDispatcher(timeConfig.timeDispatcher());
    service.setSessionFactory(sessionFactory);
    return service;
}


/**
 * @return <p>Request scoped bean that allows LoggableTransaction instances to be created and accessed on a request.<br/>
 * Consult <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factory-scopes-other-injection">Bean Factory Scopes</a></p>
 */
@Bean
@Scope(value="request", proxyMode=ScopedProxyMode.INTERFACES)
public Token<LoggableTransaction> loggableTxToken() {
    // XXX Is this is the correct way to specify a request-scoped bean?
    LoggableTransactionToken token = new LoggableTransactionToken();
    return token;
}
@Around("com.spp.mui.aop.Advisables.transactionLoggable()")
public Object logTransaction(ProceedingJoinPoint pjp) throws Throwable {
    // Prepare to log the execution time of the method call..
    long t0 = 0;
    t0 = System.currentTimeMillis();

    Object resultObject = null;

    try {
        resultObject = pjp.proceed();
    } catch (Throwable t) {
        logFailedTransactionAndRethrow(pjp, t0, t);
    }

    logSuccessfulTransaction(pjp, t0, resultObject);

    return resultObject;
}