在Grails中自动安装定制的Spring组件

kas*_*tti 5 grails spring spring-annotations

我有一个定制的Spring,它捆绑在一个jar中,然后设置为我的Grails应用程序的依赖项.我在resoueces.groovy中使用importBeans语句加载bean的app-context

beans = {
  importBeans('classpath:app-context-my-component.xml')
}
Run Code Online (Sandbox Code Playgroud)

app-context-my-component.xml具有一定的bean定义,并以下线

<context:annotation-config />
<context:property-placeholder location="classpath:my-component.properties" />
Run Code Online (Sandbox Code Playgroud)

我正在尝试使用Grails的组件使用注释@Component("myComponent").

Grails正在加载外部应用程序上下文.我知道这是因为我首先在classpath上没有.properties文件,并且在我的@Value声明中我们没有丢失属性的回退机制.

在Grails控制器中,组件用作

class MyController {

  def myComponent

  def someaction() {
    myComponent.doSomething()
  }
}
Run Code Online (Sandbox Code Playgroud)

结果是NullPointerException,即组件的自动装配根本不起作用.我尝试在控制器中使用@Autowired,但是这给了我一些奇怪的问题,我认为这不是我想要的道路.

正在使用的Grails版本是2.3.6 Spring组件也设置为使用Spring版本3.2.7以避免不兼容.

UPDATE

现在再次掌握这个问题的时间,我设置了Spring日志记录,以便弄清楚会发生什么.好吧,Spring上下文加载会产生大量的日志,但这就是我设法从整个过程中获取的内容

INFO xml.XmlBeanDefinitionReader Loading XML bean definitions from class path resource [app-context-my-component.xml]
INFO support.PropertySourcesPlaceholderConfigurer Loading properties file from class path resource [my-component.properties]
DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public myapp.external.MyComponent myapp.MyService.getMyComponentClient()
DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public myapp.external.MyComponent myapp.MyService.getMyComponentClient()
DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public myapp.external.MyComponent myapp.MyService.getMyComponentClient()
DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public void myapp.MyService.setMyComponentClient(myapp.external.MyComponent)
DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public void myapp.MyService.setMyComponentClient(myapp.external.MyComponent)
DEBUG framework.CglibAopProxy Unable to apply any optimisations to advised method: public void myapp.MyService.setMyComponentClient(myapp.external.MyComponent)
Run Code Online (Sandbox Code Playgroud)

我更改了日志的命名空间,但myapp.external命名空间引用了外部jar包,myapp命名空间引用了Grails应用程序命名空间.我已经更改了用法,因此外部组件是从服务而不是直接从Controller使用的,但该细节在行为上没有变化.

根据我的理解,Spring上下文加载进展顺利.

更新2

根据@ th3morg的回答,我有一个想法,只尝试使用基于XML的配置,从bean中跳过所有@Component和这样的注释.它奏效了!现在Grails设法导入bean,不再使用NPE.

虽然这至少部分地解决了我的问题.我仍然对可以使用Spring注释的解决方案感兴趣.

th3*_*org 6

您应该确保在jar中设置组件扫描.在http://grails.org/doc/latest/guide/spring.html#theBeanBuilderDSLExplained中查看标题为"使用Spring命名空间"的部分.如果无法修改jar,也可以使用resources.xml并将组件扫描添加到该文件中.

或者,您也可以逐个连接bean,尽管这很麻烦且乏味:

beans = {
  myComponent(com.my.MyComponent){
    someOtherService = ref('someOtherService') //if there are other beans to wire by name
    propertyOne = "x"
    propertyTwo = 2
  }
}
Run Code Online (Sandbox Code Playgroud)