gpt4 book ai didi

maven - 如何在 Maven 原型(prototype)中提供自定义逻辑?

转载 作者:行者123 更新时间:2023-12-04 01:13:32 25 4
gpt4 key购买 nike

我对创建 Maven 原型(prototype)很感兴趣,并且我认为我已经掌握了大部分基础知识。但是,我坚持的一件事是,有时我想使用自定义逻辑来填写模板。例如,如果有人生成我的原型(prototype)并将 artifactId 指定为 hello-world,我想生成一个名为 HelloWorld 的类,它只打印出“Hello World!”。到控制台。如果另一个人使用 artifactId = howdy-there 生成它,生成的类将是 HowdyThere,它会打印出“你好!”。

我知道在幕后,Maven 的原型(prototype)机制利用了 Velocity 模板引擎,所以我在 creating custom directives 上阅读了这篇文章.这似乎是我正在寻找的,所以我创建了一个名为 HyphenatedToCamelCaseDirective 的类,它扩展了 org.apache.velocity.runtime.directive.Directive。在那个类中,我的 getName() 实现返回“hyphenatedCamelCase”。在我的archetype-metadata.xml 文件中,我有以下...

<requiredProperties>
<requiredProperty key="userdirective">
<defaultValue>com.jlarge.HyphenatedToCamelCaseDirective</defaultValue>
</requiredProperty>
</requiredProperties>

我的模板类看起来像这样......

package ${package};

public class #hyphenatedToCamelCase('$artifactId') {

// userdirective = $userdirective
public static void main(String[] args) {
System.out.println("#hyphenatedToCamelCase('$artifactId')"));
}
}

在我安装我的原型(prototype)然后执行原型(prototype):通过指定 artifactId = howdy-there 和 groupId = f1.f2 生成之后,生成的类看起来像这样......

package f1.f2;

public class #hyphenatedToCamelCase('howdy-there') {

// userdirective = com.jlarge.HyphenatedToCamelCaseDirective
public static void main(String[] args) {
System.out.println("#hyphenatedToCamelCase('howdy-there')"));
}
}

结果表明,即使 userdirective 的设置方式符合我的预期,它并没有像我希望的那样评估 #hyphenatedToCamelCase 指令。在指令类中,我有 render 方法将消息记录到 System.out,但该消息没有显示在控制台中,因此我相信该方法从未在 archetype:generate 期间执行。

我在这里遗漏了一些简单的东西,还是这种方法不是可行的方法?

最佳答案

archetype-metatadata xml 的必需属性部分用于将附加属性传递给速度上下文,它是 不是 用于传递速度引擎配置。因此,设置一个名为 userDirective 的属性只会使变量 $userDirective 可用,并且不会向速度引擎添加自定义指令。

如果您查看源代码,maven-archetype 插件使用的速度引擎不依赖于任何外部属性源进行配置。 generates the project 的代码依赖于 VelocityComponent 的 Autowiring (由 plexus 容器)实现.

这是初始化速度引擎的代码:

public void initialize()
throws InitializationException
{
engine = new VelocityEngine();

// avoid "unable to find resource 'VM_global_library.vm' in any resource loader."
engine.setProperty( "velocimacro.library", "" );

engine.setProperty( RuntimeConstants.RUNTIME_LOG_LOGSYSTEM, this );

if ( properties != null )
{
for ( Enumeration e = properties.propertyNames(); e.hasMoreElements(); )
{
String key = e.nextElement().toString();

String value = properties.getProperty( key );

engine.setProperty( key, value );

getLogger().debug( "Setting property: " + key + " => '" + value + "'." );
}
}

try
{
engine.init();
}
catch ( Exception e )
{
throw new InitializationException( "Cannot start the velocity engine: ", e );
}
}

有一种添加自定义指令的 hacky 方式。您在上面看到的属性是从 components.xml 中读取的。 plexus-velocity-1.1.8.jar 中的文件。所以打开这个文件并添加你的配置属性
<component-set>
<components>
<component>
<role>org.codehaus.plexus.velocity.VelocityComponent</role>
<role-hint>default</role-hint>
<implementation>org.codehaus.plexus.velocity.DefaultVelocityComponent</implementation>
<configuration>
<properties>
<property>
<name>resource.loader</name>
<value>classpath,site</value>
</property>
...
<property>
<name>userdirective</name>
<value>com.jlarge.HyphenatedToCamelCaseDirective</value>
</property>
</properties>
</configuration>
</component>
</components>
</component-set>

接下来将您的自定义指令类文件添加到此 jar 并运行 archetype:generate。

如您所见,这是非常脆弱的,您需要想办法分发这个被黑的 plexus-velocity jar。根据您计划使用此原型(prototype)的目的,可能值得付出努力。

关于maven - 如何在 Maven 原型(prototype)中提供自定义逻辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16701772/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com