【发布时间】:2014-10-15 03:46:52
【问题描述】:
我有一个定制的 Spring,它捆绑在一个 jar 中,然后将其设置为我的 Grails 应用程序的依赖项。我使用 resoueces.groovy 中的 importBeans 语句为 bean 加载应用程序上下文,例如
beans = {
importBeans('classpath:app-context-my-component.xml')
}
app-context-my-component.xml 有一些 bean 定义和以下几行
<context:annotation-config />
<context:property-placeholder location="classpath:my-component.properties" />
我尝试与 Grails 一起使用的组件带有 @Component("myComponent") 注释。
Grails 正在加载外部应用程序上下文。我知道这一点是因为我首先在类路径中没有 .properties 文件,并且在我的 @Value 声明中没有用于丢失属性的回退机制。
在Grails控制器中,组件用作
class MyController {
def myComponent
def someaction() {
myComponent.doSomething()
}
}
结果是 NullPointerException,即组件的自动装配根本不起作用。我尝试在控制器中使用@Autowired,但这给出了一个奇怪的问题,我认为这不是我想走的路。
使用的 Grails 版本是 2.3.6 Spring 组件也设置为使用 Spring 版本 3.2.7 以避免不兼容。
更新
现在又有时间解决这个问题了,我设置了 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)
我更改了日志的命名空间,但是myapp.external命名空间是指外部jar包,myapp命名空间是指Grails应用程序命名空间。我已经更改了用法,以便从服务中使用外部组件,而不是直接从控制器中使用,但该细节的行为没有改变。
据我了解,Spring 上下文加载进展顺利。
更新 2
根据 @th3morg 的回答,我想到了仅尝试使用基于 XML 的配置,跳过 bean 中的所有 @Component 和此类注释。它奏效了!现在 Grails 设法导入 bean,不再导致 NPE 使用。
虽然这解决了我的问题,至少部分解决了。我仍然对可以使用 Spring 注释的解决方案感兴趣。
【问题讨论】:
-
在 Grails 的这一领域还没有真正深入研究,无法给出确定的答案。但是,尝试通过将
grails.spring.bean.packages = [ "com.sample.app..." ]添加到Config.groovy(定义myComponent的包或父包,Grails 将扫描子包)来告诉Grails 扫描哪个包(s) -
@Andrew 感谢您的建议,但没有任何效果。
-
嗯,抱歉导致不好。如果可能的话(考虑到你提到的关于捆绑 jar 的内容,这是一个很长的机会......)你也可以尝试将 Spring XML 移动到
grails-app/conf/spring/下名为resources.xml的文件中 -
@JAndy 您能否详细说明您希望如何使用注释?您是说 Grails 能够进行组件扫描以连接您的 XML 项目中定义的 bean?在这里查看标题为“使用 Spring 命名空间”的部分 grails.org/doc/latest/guide/…
-
好吧,我错过了 Spring 配置中的整个组件扫描。将它添加到 resources.groovy 会有所帮助,但是将它放在 Spring 模块上会更简单,因为在 Grails 中只需使用 importBeans()。
标签: spring grails spring-annotations