从 Java 类访问 Config.groovy

Posted

技术标签:

【中文标题】从 Java 类访问 Config.groovy【英文标题】:Access Config.groovy from Java class 【发布时间】:2012-10-20 21:52:38 【问题描述】:

当我的 Grails 应用程序启动时,我还会在后台启动 Spring Integration and Batch 进程。我想在 Config.groovy 文件中存储一些数据库连接属性,但是如何从集成/批处理过程中使用的 Java 类访问它们?

我找到了这个帖子:

Converting Java -> Grails ... How do I load these properties?

建议使用:

private Map config = ConfigurationHolder.getFlatConfig();

后跟类似:

String driver = (String) config.get("jdbc.driver");

这实际上工作正常(从 Config.groovy 正确加载属性)但问题是 ConfigurationHolder 在被弃用之后。我发现处理该问题的任何线程似乎都是 Grails 特定的,并建议使用依赖注入,就像在这个线程中一样:

How to access Grails configuration in Grails 2.0?

那么有没有不推荐的方法来从 Java 类文件中访问 Config.groovy 属性?

【问题讨论】:

accepted answer of the question you linked to中的第二种方法有什么问题? 嗨蒂姆,为回复干杯。我将我的 java 类作为 bean 放入资源文件中(具有 grailsApplication 的属性和 grailsApplication 的引用),并将以下行添加到我的类中:private GrailsApplication grailsApplication;用 getter 和 setter。但是当我尝试通过 ConfigObject config = grailsApplication.getConfig(); 访问它时它似乎是空的并且错误了。任何想法我做错了什么?谢谢 你想从哪里访问它?您不能在构造函数中使用依赖注入的bean,例如,您需要声明一个用@PostConstruct 注释的方法并将需要grailsApplication 的逻辑放在那里,或者使用构造函数参数注入而不是setter注射。 嗨,Ian,我不想在构造函数中访问它,只是在一个名为 connect 的单独方法中访问它,该方法由 Spring Integration 组件之一调用。文件配置文件包含我需要的数据库详细信息/凭据。所以我上面贴的那行就用在那里了。 Spring 集成组件是从 Spring 上下文中获取您的类的实例还是构建自己的实例?依赖注入仅适用于前一种情况。 【参考方案1】:

刚刚签入了一些我现有的代码,我使用this method described by Burt Beckwith

创建一个新文件:src/groovy/ctx/ApplicationContextHolder.groovy

package ctx

import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import javax.servlet.ServletContext

import org.codehaus.groovy.grails.commons.GrailsApplication
import org.codehaus.groovy.grails.plugins.GrailsPluginManager
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware

@Singleton
class ApplicationContextHolder implements ApplicationContextAware 
  private ApplicationContext ctx

  private static final Map<String, Object> TEST_BEANS = [:]

  void setApplicationContext(ApplicationContext applicationContext) 
    ctx = applicationContext
  

  static ApplicationContext getApplicationContext() 
    getInstance().ctx
  

  static Object getBean(String name) 
    TEST_BEANS[name] ?: getApplicationContext().getBean(name)
  

  static GrailsApplication getGrailsApplication() 
    getBean('grailsApplication')
  

  static ConfigObject getConfig() 
    getGrailsApplication().config
  

  static ServletContext getServletContext() 
    getBean('servletContext')
  

  static GrailsPluginManager getPluginManager() 
    getBean('pluginManager')
  

  // For testing
  static void registerTestBean(String name, bean) 
    TEST_BEANS[name] = bean
  

  // For testing
  static void unregisterTestBeans() 
     TEST_BEANS.clear()
  

然后,编辑 grails-app/config/spring/resources.groovy 以包括:

  applicationContextHolder(ctx.ApplicationContextHolder)  bean ->
    bean.factoryMethod = 'getInstance'
  

然后,在你的文件里面src/java或者src/groovy,你可以调用:

GrailsApplication app = ApplicationContextHolder.getGrailsApplication() ;
ConfigObject config = app.getConfig() ;

【讨论】:

【参考方案2】:

只是为了注册,在 Grails 2.x 中,有一个 Holders class 替换了这个已弃用的持有者。您可以使用它在静态上下文中访问grailsApplication

【讨论】:

这似乎取代了 Burt 的 ApplicationContextHolder,因为它提供了该解决方案的大部分内容,还解决了静态分配问题。【参考方案3】:

我不知道为什么这不起作用,但我可以完全建议一种替代方法。 Grails 设置了一个PropertyPlaceholderConfigurer,它的值来自grailsApplication.config,所以你可以声明一个

public void setDriver(String driver)  ... 

在你的课上然后说

<bean class="com.example.MyClass" id="exampleBean">
  <property name="driver" value="$jdbc.driver" />
</bean>

如果您使用 bean DSL,这也适用于 resources.groovy,但您必须记住使用 单引号 而不是双引号:

exampleBean(MyClass) 
  driver = '$jdbc.driver'

使用 "$jdbc.driver" 不起作用,因为这会被 Groovy 解释为 GString 并且(无法)在处理 resources.groovy 时解决,而您需要将文字 $... 表达式作为属性值稍后由占位符配置器解析。

【讨论】:

以上是关于从 Java 类访问 Config.groovy的主要内容,如果未能解决你的问题,请参考以下文章

从 Java 类访问 Config.groovy

从 Java 匿名类访问“this”

从 Java 中的另一个类访问 berkeley db

Java:直接从同一类的另一个实例访问私有字段

如何从另一个类(java)访问主类的变量?

从 Java 中的基类访问子类字段