来自 the Grails documentation和 this题:
For general configuration Grails provides two files:
- grails-app/conf/BuildConfig.groovy
- grails-app/conf/Config.groovy
Both of them use Groovy's ConfigSlurper syntax. The first, BuildConfig.groovy, is for settings that are used when running Grails commands, such as compile, doc, etc. The second file, Config.groovy, is for settings that are used when your application is running. This means that Config.groovy is packaged with your application, but BuildConfig.groovy is not.
这是关于
log4j
的摘录框架:Grails uses its common configuration mechanism to provide the settings for the underlying Log4j log system, so all you have to do is add a log4j setting to the file grails-app/conf/Config.groovy.
我有一个包含这两个文件的项目:
grails-app/conf/BuildConfig.groovy
和 grails-app/conf/Config.groovy
.项目使用log4j
实用程序,所以一些设置(包括一个函数)放在 中。 config.groovy 文件。现在,根据我引用的文档,它是正确的文件,因为我想使用日志实用程序来运行应用程序,而不是编译它。有趣的是,这些设置在我运行
mvn package
时使用在我的项目中 - log4j
中的函数设置被执行。根据两者the documentation和 the question情况不应该是这样。
我知道可以使用
grailsApplication
访问这些设置:def recipient = grailsApplication.config.foo.bar.hello
所以我搜索了我的项目,发现了
grailsApplication
的一些用法。 ,但与 log4j 设置无关。将 log4j 设置放置在 中的其他可能原因是什么? config.groovy 期间使用的文件
mvn package
?我错过了什么?更新:当我使用
mvn package
时,上述配置似乎有效第一次构建我的项目。下次跑 mvn package
, log4j
来自 Config.groovy
的配置文件被使用。如果我删除作业工作区,它会再次正常工作。
最佳答案
有一件重要的事情值得一提。即使 Config.groovy
由应用程序在运行时使用,它必须编译为 Java 的 Config.class
首先。打包时,应用程序编译器必须访问此文件并将其编译为字节码。看看我粘贴在下面的 list ,它来自我工作区中的一个 Grails 应用程序:
命令:
ls -l target/classes | awk '{print $8}'
输出:
application.properties
BootStrap.class
BootStrap$_closure1.class
BootStrap$_closure2.class
BuildConfig.class
BuildConfig$_run_closure1.class
BuildConfig$_run_closure1_closure2.class
BuildConfig$_run_closure1_closure3.class
BuildConfig$_run_closure1_closure4.class
BuildConfig$_run_closure1_closure5.class
com
Config.class
Config$_run_closure1.class
Config$_run_closure1_closure4.class
Config$_run_closure1_closure4_closure5.class
Config$_run_closure1_closure4_closure5_closure6.class
Config$_run_closure2.class
Config$_run_closure2_closure7.class
Config$_run_closure2_closure8.class
Config$_run_closure3.class
DataSource.class
DataSource$_run_closure1.class
DataSource$_run_closure2.class
DataSource$_run_closure3.class
DataSource$_run_closure3_closure4.class
DataSource$_run_closure3_closure4_closure7.class
DataSource$_run_closure3_closure5.class
DataSource$_run_closure3_closure5_closure8.class
DataSource$_run_closure3_closure6.class
DataSource$_run_closure3_closure6_closure9.class
DataSource$_run_closure3_closure6_closure9_closure10.class
resources.class
resources$_run_closure1.class
UrlMappings.class
UrlMappings$__clinit__closure1.class
UrlMappings$__clinit__closure1_closure2.class
UrlMappings$__clinit__closure1_closure2_closure3.class
你可以看到
Config.groovy
文件被编译为 Config.class
文件和所有在 Config.groovy
中使用的闭包被编译为 Java 的匿名类(例如 Config$_run_closure1_closure4.class
)。这就是为什么如果你把一些执行任何逻辑的代码放到 Config.groovy
您必须期望它会被编译和执行,因为已编译的类扩展了 groovy.lang.Script
它执行 Groovy 脚本文件的主体。您可以在下面找到 Groovy.class
的内容文件看起来像:命令:
javap -l target/classes/Config.class
输出:
Compiled from "Config.groovy"
public class Config extends groovy.lang.Script {
public static transient boolean __$stMC;
public static long __timeStamp;
public static long __timeStamp__239_neverHappen1501076781354;
public Config();
LocalVariableTable:
Start Length Slot Name Signature
4 4 0 this LConfig;
public Config(groovy.lang.Binding);
LocalVariableTable:
Start Length Slot Name Signature
4 21 0 this LConfig;
4 21 1 context Lgroovy/lang/Binding;
public static void main(java.lang.String...);
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 args [Ljava/lang/String;
public java.lang.Object run();
LineNumberTable:
line 14: 4
line 17: 43
line 18: 126
line 24: 194
line 26: 233
line 30: 296
line 31: 323
line 38: 376
line 42: 419
line 45: 453
line 63: 473
line 65: 507
line 68: 550
line 70: 595
line 72: 631
line 74: 679
line 77: 724
line 80: 777
line 84: 822
line 86: 867
line 88: 912
line 99: 932
LocalVariableTable:
Start Length Slot Name Signature
0 964 0 this LConfig;
public java.lang.Object this$dist$invoke$3(java.lang.String, java.lang.Object);
LocalVariableTable:
Start Length Slot Name Signature
0 68 0 this LConfig;
0 68 1 name Ljava/lang/String;
0 68 2 args Ljava/lang/Object;
public void this$dist$set$3(java.lang.String, java.lang.Object);
LocalVariableTable:
Start Length Slot Name Signature
0 53 0 this LConfig;
0 53 1 name Ljava/lang/String;
0 53 2 value Ljava/lang/Object;
public java.lang.Object this$dist$get$3(java.lang.String);
LocalVariableTable:
Start Length Slot Name Signature
0 46 0 this LConfig;
0 46 1 name Ljava/lang/String;
protected groovy.lang.MetaClass $getStaticMetaClass();
public static void __$swapInit();
static {};
public int super$1$hashCode();
public void super$3$printf(java.lang.String, java.lang.Object);
public void super$3$printf(java.lang.String, java.lang.Object[]);
public void super$3$setProperty(java.lang.String, java.lang.Object);
public boolean super$1$equals(java.lang.Object);
public void super$1$finalize();
public groovy.lang.Binding super$3$getBinding();
public void super$3$print(java.lang.Object);
public void super$3$setBinding(groovy.lang.Binding);
public java.lang.Object super$3$evaluate(java.io.File);
public java.lang.String super$1$toString();
public java.lang.Object super$3$evaluate(java.lang.String);
public void super$2$setMetaClass(groovy.lang.MetaClass);
public void super$1$notify();
public java.lang.Object super$3$invokeMethod(java.lang.String, java.lang.Object);
public java.lang.Object super$1$clone();
public void super$1$wait(long, int);
public void super$1$wait(long);
public void super$1$wait();
public groovy.lang.MetaClass super$2$getMetaClass();
public java.lang.Class super$1$getClass();
public void super$3$run(java.io.File, java.lang.String[]);
public void super$3$println(java.lang.Object);
public void super$1$notifyAll();
public java.lang.Object super$3$getProperty(java.lang.String);
public void super$3$println();
static java.lang.Class class$(java.lang.String);
}
更新
现在明白为什么
Config.groovy
执行我们需要深入研究 grails package
时会发生什么正在被执行。运行 grails package
命令使 _GrailsPackage.groovy
来自 grails-core 的脚本正在执行。 packageApp
目标电话GrailsProjectPackager.packageApplication()
https://github.com/grails/grails-core/blob/2.4.x/grails-scripts/src/main/scripts/_GrailsPackage.groovy#L48
此方法调用
createConfig()
辅助类:https://github.com/grails/grails-core/blob/2.4.x/grails-project-api/src/main/groovy/org/codehaus/groovy/grails/project/packaging/GrailsProjectPackager.groovy#L274
在
createConfig()
方法实现我们可以找到ConfigSlurper.parse(script)
执行:https://github.com/grails/grails-core/blob/2.4.x/grails-project-api/src/main/groovy/org/codehaus/groovy/grails/project/packaging/GrailsProjectPackager.groovy#L345
这是一个解析脚本并最终调用
script.run()
的 Groovy 类。在解析的脚本上。使用调试器很容易找到 - 请查看我的视频,我在此特定示例中展示了如何执行此操作:https://www.youtube.com/watch?v=s2PN6TjFjUI我希望它有帮助。
关于maven - Grails:为什么在编译期间执行 Config.groovy 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46279525/