来自Spring的BeanCreationException,注释为“@Context”和“@Loggable”

时间:2015-05-18 06:10:20

标签: java spring service cxf spring-annotations

我有使用Spring,Apache CXF和Jetty的Web应用程序。 Spring不喜欢在我的一个类中为方法添加一个名为@Loggable的注释。

首先,注释@Loggable链接到类LogAspect,它记录请求和响应消息:

@Aspect
@Component
public class LogAspect {

     ...
     ...
        @Around("execution(* * (..)) && @annotation(Loggable)")
        public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {

          ...
          if ( returnValue != null) {
                logger.infoRequestResponse(clazz, name, joinPoint.getArgs(), returnValue);
          } else {
                logger.infoRequestResponse(clazz, name, joinPoint.getArgs(), "void");
          }
          return returnValue;
        }
}

我猜它与@Context - 注释有关,以及在什么时候注入的内容。

该类是RESTful服务的实现。私人会员request上有注释@Context

@org.springframework.stereotype.Service(value = "resellerService")
public class ResellerServiceImpl implements ResellerService {

    @Context
    private HttpServletRequest request;
...
...
    @Loggable
    @Override
    public Response isUserLoggedIn() {
        Optional<ResellerSession> maybeSession = getSessionFromContext();
        return Response.ok(maybeSession.isPresent()).build();
    }

@Loggable方法上添加isUserLoggedIn - 注释会产生以下异常:

        WARN  org.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext@79a9e51e{/,file:/home/lars/intellij_wspace/app/app-node/trunk/src/main/webapp/,STARTING}{src/main/webapp/}
        org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resellerServiceServer': Invocation of init method failed; nested exception is org.apache.cxf.service.factory.ServiceConstructionException
            at [SNIP]
    org.eclipse.jetty.webapp.WebAppContext.startWebapp(WebAppContext.java:1349) ~[jetty-webapp-9.2.10.v20150310.jar:9.2.10.v20150310]
            at ]
[SNIP]
        Caused by: org.apache.cxf.service.factory.ServiceConstructionException: null
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:219) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_80]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_80]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_80]
            at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_80]
            at 
    [SNIP]
            ... 33 common frames omitted
        Caused by: java.lang.IllegalArgumentException: Can not set javax.servlet.http.HttpServletRequest field com.app.service.impl.reseller.ResellerServiceImpl.request to com.sun.proxy.$Proxy109
            at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) ~[na:1.7.0_80]
            at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) ~[na:1.7.0_80]
            at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:55) ~[na:1.7.0_80]
            at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:75) ~[na:1.7.0_80]
            at java.lang.reflect.Field.set(Field.java:741) ~[na:1.7.0_80]
            at org.apache.cxf.jaxrs.utils.InjectionUtils$1.run(InjectionUtils.java:192) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at java.security.AccessController.doPrivileged(Native Method) ~[na:1.7.0_80]
            at org.apache.cxf.jaxrs.utils.InjectionUtils.injectFieldValue(InjectionUtils.java:188) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.utils.InjectionUtils.injectContextProxiesAndApplication(InjectionUtils.java:1058) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.injectContexts(JAXRSServerFactoryBean.java:405) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.updateClassResourceProviders(JAXRSServerFactoryBean.java:429) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
            at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:162) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]

所以我尝试在请求中删除@Context,然后将其添加到setter方法中:

private HttpServletRequest request;

@Context
public void setRequest(HttpServletRequest request) { this.request = request; }

这给了我这个例外:

 WARN  org.eclipse.jetty.webapp.WebAppContext - Failed startup of context o.e.j.w.WebAppContext@25ddbf05{/,file:/home/lars/intellij_wspace/app/app-node/trunk/src/main/webapp/,STARTING}{src/main/webapp/}
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resellerServiceServer': Invocation of init method failed; nested exception is org.apache.cxf.service.factory.ServiceConstructionException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:539) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:755) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480) ~[spring-context-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:403) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:306) ~[spring-web-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    ...
    ...
Caused by: org.apache.cxf.service.factory.ServiceConstructionException: null
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:219) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_80]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_80]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_80]
    at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_80]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1702) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1641) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1570) ~[spring-beans-4.1.6.RELEASE.jar:4.1.6.RELEASE]
    ... 33 common frames omitted
Caused by: javax.ws.rs.InternalServerErrorException: HTTP 500 Internal Server Error
    at org.apache.cxf.jaxrs.utils.SpecExceptions.toInternalServerErrorException(SpecExceptions.java:79) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.ExceptionUtils.toInternalServerErrorException(ExceptionUtils.java:106) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:472) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.reportServerError(InjectionUtils.java:458) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.injectThroughMethod(InjectionUtils.java:314) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.injectThroughMethod(InjectionUtils.java:294) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.utils.InjectionUtils.injectContextProxiesAndApplication(InjectionUtils.java:1046) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.injectContexts(JAXRSServerFactoryBean.java:405) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.updateClassResourceProviders(JAXRSServerFactoryBean.java:429) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    at org.apache.cxf.jaxrs.JAXRSServerFactoryBean.create(JAXRSServerFactoryBean.java:162) ~[cxf-rt-frontend-jaxrs-3.1.0.jar:3.1.0]
    ... 40 common frames omitted

任何人对如何解决这个问题都有任何想法?

修改

我无法显示我的整个pom.xml,但我确实有这一行 4.1.6.RELEASE

构建看起来很好。所有其他注释,如@Autowired都可以。

2 个答案:

答案 0 :(得分:0)

问题在于spring-beans-4.1.6.RELEASE.jar。

希望你添加了Spring-beans-4.1.6.jar文件Still Spring有时因某些问题无法获取jar。在这种情况下

从服务器中删除现有项目。

右键单击您的服务器,

点击清理,

右键单击您的服务器,

单击清除工作目录。

Spring MVC也可以这种方式获取jar文件,它可以正常工作

右键单击Spring MVC项目,

构建路径 - &gt;配置构建路径

将出现一个标签,

选择添加外部JAR按钮并添加所需的所有jar。

之后,单击Deployment Assembly,

单击“添加按钮”,

单击Java Build Path Entries,

单击“下一步”,

选择此窗口中显示的所有jar。

单击“完成”。

刷新您的项目,

运行项目。

截至目前,它将以正确的方式获取spring-beans-4.1.6.RELEASE.jar。希望它有所帮助。

答案 1 :(得分:0)

我现在已经收到有关如何解决此问题的帮助。简而言之,必须将@Context注释移动到类实现的接口的方法中。

解决方案如下:

  1. 删除了私人成员HttpServletRequest request及其@Context注释。
  2. HttpServletRequest参数添加到使用它的方法中。 例如:

    public Response registerUser(HttpServletRequest request,...){

  3. @Context注释添加到REST界面。 例如:

    @Path(&#34;寄存器/用户&#34)
    @POST
    @Consumes(&#34;应用/ JSON&#34)

    响应registerUser(@Context HttpServletRequest httpServletRequest,..);