SpringBank 开发日志 使用maven构建dubbo服务的可执行jar包

写这篇日志的时候,我已经完成了这个目标,并且中间经历了一次面试。现在回过头看,已经觉得印象不那么深刻了,果然还是一边思考,一边记录这样最好。但我还是严格要求自己,从新做了梳理,对相关配置进行了整理和说明,以下。

谁是启动类

既然是构建可执行的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>

 

原文地址:https://www.cnblogs.com/heben/p/7920786.html