写这篇日志的时候,我已经完成了这个目标,并且中间经历了一次面试。现在回过头看,已经觉得印象不那么深刻了,果然还是一边思考,一边记录这样最好。但我还是严格要求自己,从新做了梳理,对相关配置进行了整理和说明,以下。
谁是启动类
既然是构建可执行的JAR包,首先要明确启动类是谁。一开始做的时候,我是使用的自己写的启动类
public static void main(String[] args) { new ClassPathXmlApplicationContext("classpath:META-INF/spring/start-config.xml"); log.debug("IocMain 启动完成"); }
后来了解到,dubbo自带启动类,并且实现了优雅关机,所以无论是在eclipse中测试,还是打包指定启动类,都改为使用 dubbo自带的了。
包应该产生在哪个项目里
我一开始认为包应该产生在springbank-parent里,并且我做了一些尝试,实际上是行不通的,parent的packaging不能指定为jar或者war而只能是pom。在这个过程中我也意识到自己对maven打包的理解是错误的。任何一个项目,只要packaging配置为jar(jar为默认配置),则该项目打包后会形成jar包.
具体配置
当时折腾了许久,主要是要配合dubbo启动类的特点,做一些特别的配置。下面是配置文件,刚刚我特意又增加了许多注释,这样以后就能看的明白了
<build> <!-- resources是一个资源元素列表,每个资源元素都描述了与这个项目相关的文件和包含文件的位置 --> <resources> <!-- 目的:将spring相关文件打包后放到jar包根目录下 --> <!-- 理解:如果没有这个配置,将会导致springbank-portal等项目打完包之后没有任何spring配置文件。所以我对resource标签的理解就是,它是一个资源配置 例如下面这个这个配置,其中directory就是资源在源码项目所在的位置,targetPath的意思就是打包之后要放在哪里,所谓放置在${project.build.directory}/classes,实际上就是放在jar包的根目录 --> <resource> <targetPath>${project.build.directory}/classes</targetPath> <directory>src/main/resources</directory> <filtering>false</filtering> </resource> <!-- 目的:结合com.alibaba.dubbo.container.Main需要做的配置 --> <!-- 理解:结合上一个resource的描述,可以看出,这里是将start-config.xml文件放到了jar包里的META-INF/spring目录下 之所以要这样放,是因为dubbo默认的启动类,是从META-INF/spring目录下加载spring文件。其实这里的配置是一个难点,因为既要考虑到能让dubbo加载到start-config.xml 也要考虑到能让start-config.xml里面的import能够找到相关的资源文件。我反复尝试了很多很多次,结合上面的resource配置,即将spring文件直接打包时放在classpath,最终在start-config.xml才能通过类似classpath:infrastructure.xml方式引用到相关文件--> <resource> <!-- targetPath 指定放置构建资源集的目录结构.目标路径默认为基础目录.在JAR中打包的资源通常指定的目标路径是META-INF,project.build.directory缺省为target --> <targetPath>${project.build.directory}/classes/META-INF/spring</targetPath> <!-- 这个元素的值定义了资源被找到的地方.构建的默认目录是$ {basedir} / src / main / resources --> <directory>src/main/resources</directory> <filtering>true</filtering> <!-- 一组文件模式,使用*作为通配符,指定要作为资源包含在指定目录下的文件 --> <includes> <include>start-config.xml</include> </includes> </resource> </resources> <!-- pluginManagement之于plugins 如同 dependencyManagement之于dependencies 。是一样的,所以我认为这里做这样一个配置,对我的目的并没有用,而且我确实也不理解这个配置的涵义,先放在这里,后面来研究 --> <pluginManagement> <plugins> <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself. --> <plugin> <groupId>org.eclipse.m2e</groupId> <artifactId>lifecycle-mapping</artifactId> <version>1.0.0</version> <configuration> <lifecycleMappingMetadata> <pluginExecutions> <pluginExecution> <pluginExecutionFilter> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <versionRange>[1.0,)</versionRange> <goals> <goal>copy-dependencies</goal> </goals> </pluginExecutionFilter> <action> <ignore /> </action> </pluginExecution> </pluginExecutions> </lifecycleMappingMetadata> </configuration> </plugin> </plugins> </pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.5</version> <configuration> <!-- 指定source和target的版本 --> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <!-- 打包配置,配置了哪些内容需要打包到jar里,配置了manifest文件的内容 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <configuration> <!-- 将target/classes下所有内容放到jar里 --> <classesDirectory>target/classes</classesDirectory> <archive> <manifest> <!-- 是否创建一个Class-Path清单条目,默认值是false, 改为true,因为我们确实需要这样一个文件,它会告诉虚拟机启动类是谁,哪些东东要加入classpath--> <addClasspath>true</addClasspath> <mainClass>com.alibaba.dubbo.container.Main</mainClass> <!-- 是否使用唯一的时间戳快照版本而不是-SNAPSHOT版本.默认值是true --> <useUniqueVersions>false</useUniqueVersions> <!-- 将作为所有Class-Path条目前缀的文本,默认值是"" --> <classpathPrefix>lib/</classpathPrefix> </manifest> <!-- A list of key/value pairs to add to the manifest. --> <manifestEntries> <Class-Path>.</Class-Path> </manifestEntries> </archive> <outputDirectory>${standalone.output.dir}</outputDirectory> </configuration> <executions> <execution> <id>jar</id> <phase>package</phase> <goals> <goal>jar</goal> </goals> </execution> </executions> </plugin> <!-- 依赖打包配置,目的是将自己的依赖也打包,然后放到指定的目录下 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-dependency-plugin</artifactId> <executions> <execution> <id>copy-dependencies</id> <phase>package</phase> <goals> <goal>copy-dependencies</goal> </goals> <configuration> <type>jar</type> <includeTypes>jar</includeTypes> <useUniqueVersions>fasle</useUniqueVersions> <outputDirectory>${standalone.output.dir}/lib</outputDirectory> </configuration> </execution> </executions> </plugin> </plugins> </build>