簡體   English   中英

Grails 4.1.1 Data Service無法注入Command Object: NoSuchBeanDefinitionException

[英]Grails 4.1.1 Data Service cannot be injected into Command Object: NoSuchBeanDefinitionException

我有一個簡單的控制器/命令/數據服務設計:

@Secured("ROLE_BACKEND")
class CommunityController {
    static namespace = "api"

    static allowedMethods = [index: "GET"]

    def index(GetCommunitiesRequest request) {
        respond request.execute(params).get()
    }
}
@CompileStatic
class GetCommunitiesRequest implements Validateable {
    @Autowired
    CommunityService communityService

    GetCommunitiesRequest() {
        println "Hello"
    }

    Boolean withPartners = false
    Integer max

    Try<List<Map>> execute(Map params) {
        def r = Try.of {
            params.max = Math.min(max ?: 10, 100)
            communityService.list(params)
        }.map {communities->
            communities.collect {it.asMap(withPartners)}
        }
    }
}
@Service(Community)
interface CommunityService {

    abstract Community get(Serializable id)

    abstract List<Community> list(Map args)

    abstract Long count()

    abstract void delete(Serializable id)

    abstract Community save(Community community)

}

這是 UrlMappings 文件(以防萬一有命名空間控制器的鏈接):

class UrlMappings {

    static mappings = {
        group "/api", {
            delete "/$controller/$id(.$format)?"(action:"delete", namespace:'api')
            get "/$controller(.$format)?"(action:"index", namespace:'api')
            get "/$controller/$id(.$format)?"(action:"show", namespace:'api')
            post "/$controller(.$format)?"(action:"save", namespace:'api')
            put "/$controller/$id(.$format)?"(action:"update", namespace:'api')
            patch "/$controller/$id(.$format)?"(action:"patch", namespace:'api')

            "/"(controller: 'application', action: 'index', namespace:"api")
            "500"(view: '/error')
            "404"(view: '/notFound')
        }

        "/$controller/$action?/$id?(.$format)?"{
            constraints {
                // apply constraints here
            }
        }

        "/"(controller: 'application', action:'index')
        "500"(view: '/error')
        "404"(view: '/notFound')
    }
}

此代碼的大部分基於 grails 在我的域 class 上使用 generate-all 時生成的代碼。顯然,添加的皺紋是命令(和 Try monad,但這應該是無關緊要的)。

當我執行此端點時,出現以下異常:

java.lang.reflect.InvocationTargetException: null
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
at org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1043)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at grails.plugin.springsecurity.rest.RestLogoutFilter.doFilter(RestLogoutFilter.groovy:82)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at grails.plugin.springsecurity.web.filter.GrailsHttpPutFormContentFilter.doFilterInternal(GrailsHttpPutFormContentFilter.groovy:54)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at grails.plugin.springsecurity.rest.RestTokenValidationFilter.processFilterChain(RestTokenValidationFilter.groovy:121)
at grails.plugin.springsecurity.rest.RestTokenValidationFilter.doFilter(RestTokenValidationFilter.groovy:89)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at grails.plugin.springsecurity.rest.RestAuthenticationFilter.doFilter(RestAuthenticationFilter.groovy:136)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doFilter(AbstractPreAuthenticatedProcessingFilter.java:124)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:64)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.pr.request.GetCommunitiesRequest': Unsatisfied dependency expressed through field 'communityService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.pr.data.service.CommunityService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1425)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:392)
at grails.artefact.Controller$Trait$Helper.initializeCommandObject(Controller.groovy:456)
... 39 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.pr.data.service.CommunityService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1717)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1273)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1227)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)
... 45 common frames omitted

關於如何開始調查此問題的任何想法? 顯然,如果您直接知道答案,歡迎您:)。

我試過的

  • 我已經嘗試逐步調試命令 object 的實例化(這就是為什么我添加了一個空的構造函數,以便能夠設置斷點),但是我正在為 ApplicationContext 層的復雜性而苦苦掙扎,我覺得我不太了解為什么這個服務 bean 沒有被注入。
    問題發生在 grails.artefact.Controller#initializeCommandObject

  • 我安裝了 grails 控制台插件,應用程序啟動后,我嘗試使用ctx.communityService訪問 communityService bean,並得到一個屬性 bean 作為響應: com.example.pr.domain.$CommunityServiceImplementation@5deeeb12

  • 在同一個 grails 控制台中,當我嘗試執行以下代碼時:

def controller = ctx.getBean("com.example.pr.http.api.CommunityController")
  
controller.initializeCommandObject(com.examplep.pr.request.GetCommunitiesRequest, "request")

我得到同樣的例外

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.pr.request.GetCommunitiesRequest': Unsatisfied dependency expressed through field 'communityService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.pr.data.service.CommunityService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

任何幫助表示贊賞。

更新 1

試圖刪除命令 object 中的@Autowired注釋。它仍然失敗,但有一個稍微不同的異常( ConversionNotSupportedException ):


org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'com.example.pr.domain.$CommunityServiceImplementation' to required type 'com.example.pr.data.service.CommunityService' for property 'communityService'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'com.example.pr.domain.$CommunityServiceImplementation' to required type 'com.example.pr.data.service.CommunityService' for property 'communityService': no matching editors or conversion strategy found

    org.springframework.beans.AbstractNestablePropertyAccessor.convertIfNecessary(AbstractNestablePropertyAccessor.java:595)
    org.springframework.beans.AbstractNestablePropertyAccessor.convertForProperty(AbstractNestablePropertyAccessor.java:609)
    org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:219)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1751)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1707)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1447)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:392)
    grails.artefact.Controller$Trait$Helper.initializeCommandObject(Controller.groovy:456)
    Script1.run(Script1.groovy:3)
    org.grails.plugins.console.ConsoleService.eval(ConsoleService.groovy:37)
    org.grails.plugins.console.ConsoleController.execute(ConsoleController.groovy:53)
    java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    org.grails.core.DefaultGrailsControllerClass$ReflectionInvoker.invoke(DefaultGrailsControllerClass.java:211)
    org.grails.core.DefaultGrailsControllerClass.invoke(DefaultGrailsControllerClass.java:188)
    org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:90)
    org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1043)
    org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:943)
    org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
    org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
    org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
    grails.plugin.springsecurity.rest.RestLogoutFilter.doFilter(RestLogoutFilter.groovy:82)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:126)
    org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:90)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:118)
    grails.plugin.springsecurity.web.UpdateRequestContextHolderExceptionTranslationFilter.doFilter(UpdateRequestContextHolderExceptionTranslationFilter.groovy:64)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    grails.plugin.springsecurity.web.filter.GrailsHttpPutFormContentFilter.doFilterInternal(GrailsHttpPutFormContentFilter.groovy:54)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    grails.plugin.springsecurity.web.filter.GrailsAnonymousAuthenticationFilter.doFilter(GrailsAnonymousAuthenticationFilter.groovy:54)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.authentication.rememberme.RememberMeAuthenticationFilter.doFilter(RememberMeAuthenticationFilter.java:158)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:158)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    grails.plugin.springsecurity.rest.RestAuthenticationFilter.doFilter(RestAuthenticationFilter.groovy:136)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter.doFilter(AbstractPreAuthenticatedProcessingFilter.java:124)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    grails.plugin.springsecurity.web.authentication.logout.MutableLogoutFilter.doFilter(MutableLogoutFilter.groovy:64)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    grails.plugin.springsecurity.web.SecurityRequestHolderFilter.doFilter(SecurityRequestHolderFilter.groovy:58)
    org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
    org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
    java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    java.base/java.lang.Thread.run(Thread.java:834)

事實證明,我錯誤地在另一個 package 中創建了我的CommunityService數據服務的副本。Grails 在嘗試實例化命令 object 時感到困惑,當時它試圖自動裝配它並且不知何故沒有報告有 2 個候選人(?)。

我有兩個相同的服務副本:

  • com.example.pr.domain.CommunityService (由generate-all生成)
  • com.example.pr.service.data.CommunityService (嘗試重新打包為更符合邏輯的 package 結構,而不是將服務放在domain包中)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM