从Maven原型生成项目时,如何为嵌套变量生成值?
首先得明确:Maven Archetype的属性替换机制是单次解析的,它没办法直接处理${${tomcat-jdbc-user}}这种嵌套的变量引用——它只会把${tomcat-jdbc-user}当作一个普通字符串,不会再去解析这个字符串对应的属性值。所以你当前的配置方式是行不通的,下面给你几个可行的解决思路:
方法1:直接引用原始属性路径(最简单)
既然tomcat-jdbc-user只是${specialized-folder}.tomcat.jdbc.user的别名,那你可以跳过这个中间变量,直接把username的value指向原始属性:
<property name="username" value="${specialized-folder}.tomcat.jdbc.user" />
当你传入specialized-folder=company时,这个属性会被解析为company.tomcat.jdbc.user,而这个属性的值正是xyz,所以username就能正确拿到xyz了。
方法2:利用Velocity模板语法实现动态解析(适合复杂场景)
如果你的原型使用的是默认的Velocity模板引擎(绝大多数Maven Archetype都是),可以在模板文件中用Velocity的语法来实现嵌套属性的解析。
比如在需要设置username的配置文件中,替换成Velocity的动态语法:
#set($targetProp = $tomcat-jdbc-user) username=$!{variables.get($targetProp)}
这里的variables是Archetype传递给Velocity上下文的对象,包含了所有定义的属性。$tomcat-jdbc-user会先被解析为company.tomcat.jdbc.user,然后variables.get($targetProp)就能拿到对应的xyz值。
方法3:直接在archetype-metadata.xml中定义username属性(适合需要用户输入的场景)
如果允许用户直接输入username的值,你可以在archetype-metadata.xml中新增一个必填的username属性:
<requiredProperties> <requiredProperty key="specialized-folder" /> <requiredProperty key="username" /> </requiredProperties>
然后在配置文件中直接使用${username}。不过这个方法的前提是你愿意让用户手动输入用户名,而不是从已有属性推导。
总结一下,方法1是最直接且无额外复杂度的解决方案,如果你的场景不需要中间变量tomcat-jdbc-user的话,优先用这个;如果必须保留中间变量的别名,那方法2的Velocity语法就能满足需求。
内容的提问来源于stack exchange,提问作者Naren

