如何用maven-jaxb2-plugin复用同项目公共XSD分包生成JAXB类?
解决方案:用Episode机制复用JAXB类并分包生成
我来帮你把这个问题拆解清楚——你提到的episode机制完全是正确的思路,核心就是先单独生成公共Schema C的类和episode绑定文件,然后在生成A和B的时候引用这个文件,让JAXB知道要复用已有的C类,而不是重复生成。下面是具体的操作步骤,不管你用命令行还是Maven都能搞定:
第一步:生成Schema C的公共类和Episode文件
首先咱们先处理公共的Schema C,把它的JAXB类生成到一个公共包(比如com.example.common),同时生成episode文件——这个文件是关键,它会记录C对应的命名空间和生成的类之间的映射关系。
命令行方式(xjc工具)
直接用JDK自带的xjc命令执行:
xjc -d target/generated-sources -p com.example.common schema/C.xsd -episode target/episode/c.episode
参数说明:
-d:指定生成类的输出目录-p:指定公共包名,所有C的类都会放在这里-episode:指定生成的episode文件路径,这个文件后面要用到
Maven方式(jaxb2-maven-plugin)
如果用Maven管理项目,在插件里添加一个专门处理Schema C的execution:
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>jaxb2-maven-plugin</artifactId> <version>2.5.0</version> <executions> <!-- 先处理公共Schema C --> <execution> <id>generate-common-schema</id> <goals> <goal>xjc</goal> </goals> <configuration> <schemaDirectory>${project.basedir}/src/main/resources/schema</schemaDirectory> <schemaIncludes> <include>C.xsd</include> </schemaIncludes> <packageName>com.example.common</packageName> <outputDirectory>${project.build.directory}/generated-sources/common</outputDirectory> <!-- 生成episode文件 --> <episodeFile>${project.build.directory}/episodes/c.episode</episodeFile> </configuration> </execution> </executions> </plugin>
第二步:生成Schema A的类到单独包,复用C的类
接下来处理Schema A,指定它自己的包(比如com.example.schemaA),同时通过-b参数(命令行)或者绑定文件配置(Maven)引用刚才生成的C的episode文件。
命令行方式
xjc -d target/generated-sources -p com.example.schemaA schema/A.xsd -b target/episode/c.episode
这里的-b参数就是告诉xjc:“这个episode文件里的命名空间对应的类已经存在了,别再重新生成,直接用现成的就行”。
Maven方式
在刚才的插件配置里再添加一个处理Schema A的execution,引用C的episode文件:
<!-- 处理Schema A,复用C的类 --> <execution> <id>generate-schemaA</id> <goals> <goal>xjc</goal> </goals> <configuration> <schemaDirectory>${project.basedir}/src/main/resources/schema</schemaDirectory> <schemaIncludes> <include>A.xsd</include> </schemaIncludes> <packageName>com.example.schemaA</packageName> <outputDirectory>${project.build.directory}/generated-sources/schemaA</outputDirectory> <!-- 引用C的episode文件 --> <bindingFiles> <bindingFile>${project.build.directory}/episodes/c.episode</bindingFile> </bindingFiles> </configuration> </execution>
第三步:生成Schema B的类到单独包,复用C的类
和Schema A的操作完全一样,只是把包名改成com.example.schemaB,Schema文件换成B.xsd就行:
命令行方式
xjc -d target/generated-sources -p com.example.schemaB schema/B.xsd -b target/episode/c.episode
Maven方式
添加第三个execution:
<!-- 处理Schema B,复用C的类 --> <execution> <id>generate-schemaB</id> <goals> <goal>xjc</goal> </goals> <configuration> <schemaDirectory>${project.basedir}/src/main/resources/schema</schemaDirectory> <schemaIncludes> <include>B.xsd</include> </schemaIncludes> <packageName>com.example.schemaB</packageName> <outputDirectory>${project.build.directory}/generated-sources/schemaB</outputDirectory> <!-- 同样引用C的episode文件 --> <bindingFiles> <bindingFile>${project.build.directory}/episodes/c.episode</bindingFile> </bindingFiles> </configuration> </execution>
关键注意点
- 确保Schema A和B里对C的命名空间引用完全正确,episode文件是通过命名空间来关联类的,命名空间不匹配的话会导致复用失败
- 生成A和B的时候,要保证C的类所在的目录已经存在(或者在类路径里),这样xjc才能找到对应的类
- 如果用IDE,记得把生成的类目录标记为“Generated Sources Root”,避免编译问题
内容的提问来源于stack exchange,提问作者Benny Bottema
相关产品推荐
相关产品推荐

