spring - 使用 Spring Bean 声明覆盖 Grails 中的服务

标签 spring grails dependency-injection

我正在创建一个包含 CustomService 的新插件,该插件旨在从现有插件中替换现有服务。遵循自定义安全实现中的模式并显示 here ,我已经将配置添加到resources.groovy,oldService(path.to.new.CustomService)。我还尝试将所有注入(inject)的类添加到该服务的闭包中。
(实际的服务名称是代码块中的 RegistrationPersonRegistrationCompositeService 和 NewRegistrationPersonRegistrationCompositeService)

我不希望原始应用程序代码对新插件有任何引用。但是,应用程序级别的 BuildConfig 将需要 plugin.location 条目。我的 resource.groovy 模组在新插件中。我在这方面的努力没有成功。我是否修改了错误的 resources.groovy?如果需要在原始应用程序代码中进行此更改,我将无法保持原始代码不变。我没有扩展原始服务,也没有使用覆盖注释。我的意图是在启动时替换服务(Spring bean)。新插件依赖于旧插件,试图管理加载这些类的操作顺序。

旧服务之前注入(inject) Controller 是否重要?这将需要我以相同的方式覆盖新插件中的 Controller 并为所需的行为注入(inject)正确的服务?

我发现文档显示在插件中,resources.groovy 将被忽略。此外,将 resources.groovy 构建成 war 也是有问题的。我还没有找到解决方案。我没有得到任何可以分享的错误,只是缺少所需的行为;原始服务正在处理请求。

//was resource.groovy - now renamed to serviceOverRide.groovy - still located in \grails-app\conf\spring of plugin
//tried this with and without the BeanBuilder. Theory: I'm missing the autowire somehow
import org.springframework.context.ApplicationContext
import grails.spring.BeanBuilder

def bb = new BeanBuilder()

bb.beans {
    registrationPersonRegistrationCompositeService(path.to.services.registration.NewRegistrationPersonRegistrationCompositeService) { bean ->
        bean.autowire = true
        registrationRestrictionCompositeService = ref("registrationRestrictionCompositeService")
        registrationPersonTermVerificationService = ref("registrationPersonTermVerificationService")
    }
    classRegistrationController(path.to.services.registration.ClassRegistrationController) { bean ->
        bean.autowire = true
        selfServiceLookupService = ref("selfServiceLookupService")
        registrationPersonRegistrationCompositeService = ref("registrationPersonRegistrationCompositeService")
    }
}
ApplicationContext appContext = bb.createApplicationContext()

附加信息:将以下行添加到 PluginGrailsPlugin.groovy。原始服务仍在处理这些请求
def dependsOn = ['appPersonRegistration': '1.0.20  > *']
List loadAfter = ['appPersonRegistration']

def doWithSpring = {
    registrationPersonCourseRegistrationCompositeService(path.to.new.registration.TccRegistrationPersonCourseRegistrationCompositeService)
}

def doWithApplicationContext = { applicationContext ->
    SecurityContextHolder.setStrategyName(SecurityContextHolder.MODE_INHERITABLETHREADLOCAL)
    DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory()
    beanFactory.registerBeanDefinition("registrationPersonCourseRegistrationCompositeService", BeanDefinitionBuilder.rootBeanDefinition(TccRegistrationPersonCourseRegistrationCompositeService.class.getName()).getBeanDefinition())
}

最佳答案

我强烈建议您阅读关于 Plugins 的文档部分。 .我推荐这个的原因是因为插件:

  • 请勿包含或使用 resources.groovy
  • 通过doWithSpring提供一种方式影响 Spring 应用

  • 按照文档中的信息,在应用程序上下文中覆盖服务应该没有问题。

    您必须使用 doWithSpring 实现对应用程序上下文的更改。这是解决您的问题的关键。

    关于spring - 使用 Spring Bean 声明覆盖 Grails 中的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36321488/

    相关文章:

    java - 接口(interface)注释未触发 AspectJ 注释切入点

    java - Spring - 两个实现之间的运行时选择

    java - 在Java中注入(inject)多个参数同一个接口(interface)

    java - 浏览器和 postman 返回结果,但 Resttemplate 由于 %26 返回 0 个结果

    spring - 如何在 Groovy spring DSL 中定义原型(prototype)作用域 bean

    java - Spring MVC(异步)与 Spring WebFlux

    grails - Grails如何获取原始请求uri

    java - 为什么 Grails 需要 Xerces?

    grails - Grails 2.0:禁用所有资源记录

    java - 具有列表值的 Guice MapBinder