Shusshu / gs-multi-module

Creating a Multi Module Project :: Learn how to build a library and package it for consumption in a Spring Boot application

Home Page:http://spring.io/guides/gs/multi-module

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

This guide shows you how to create a multi-module project with Spring Boot, in which there is a library jar and a main application that uses the library. You could also use it just to see how to build a library on its own (i.e. a jar file that is not an application).

What you’ll build

You’ll setup a simple library jar that exposes a service for simple Hello World messages, and then include the service in a web application that uses the library as a dependency. You can use the guide to learn how to do the same thing with Maven and with Gradle, but for a real project you would probably choose one or the other.

Create a Root Project

Create the directory structure

In a project directory of your choosing, create the following subdirectory structure; for example, with mkdir library application on *nix systems:

└── library
└── application

In the root of the project you will need to set up a build system, and this guide shows you how to use Maven or Gradle.

Gradle Configuration for Multi Module Project

Gradle Configuration for Multi Module Project

We recommend using the Gradle wrapper. So install the wrapper by copying it from an existing project, or by executing Gradle with the wrapper task (follow instructions in the Gradle documentation). That should get you a top level directory that looks like this:

└── library
└── application
└── gradlew
└── gradlew.bat
└── gradle
    └── wrapper
        └── gradle-wrapper.properties
        └── gradle-wrapper.jar

Windows (non-Cygwin) users execute the gradlew.bat script to build the project; everyone else uses the gradlew script. Then add a settings.gradle to the root directory to drive the build at the top level:

settings.gradle

link:initial/settings.gradle[role=include]

Maven Configuration for Multi Module Project

Maven Configuration for Multi Module Project

We recommend using the Maven wrapper. So install the wrapper by copying it from an existing project, or by executing Maven with the io.takari:maven:wrapper goal (follow instructions in the wrapper documentation). That should get you a top level directory that looks like this:

└── library
└── application
└── mvnw
└── mvnw.cmd
└── .mvn
    └── wrapper
        └── maven-wrapper.properties
        └── maven-wrapper.jar

Windows (non-Cygwin) users execute the mvnw.cmd script to build the project; everyone else uses the mvnw script. Then add a pom.xml to the root directory to drive the build at the top level:

pom.xml

link:initial/pom.xml[role=include]

Create a Library Project

Create the directory structure

In a the "library" directory, create the following subdirectory structure; for example, with mkdir -p src/main/java/hello/service on *nix systems:

└── src
    └── main
        └── java
            └── hello
                └── service

Now we need to configure a build tool (Maven or Gradle). In both cases note that the Spring Boot plugin is not used in the library project at all. The main function of the plugin is to create an executable "über-jar" which we don’t need (and don’t want) for a library. To get you started quickly, here is the complete configuration:

Gradle Configuration for Library

Gradle Configuration for Library

library/build.gradle

link:initial/library/build.gradle[role=include]

Although the Spring Boot Gradle plugin is not being used, you do want to take advantage of Spring Boot dependency management, so that is configured using the dependency-management plugin and the mavenBom from Spring Boot.

Maven Configuration for Library

Maven Configuration for Library

library/pom.xml

link:initial/library/pom.xml[role=include]

Although the Spring Boot Maven plugin is not being used, you do want to take advantage of Spring Boot dependency management, so that is configured using the spring-boot-starter-parent from Spring Boot as a parent project. An alternative would be to import the dependency management as a Bill of Materials (BOM) in the <dependencyManagement/> section of the POM.

Create a Service Component

The library will provide a MyService class that can be used by applications that depend on the library:

library/src/main/java/hello/service/MyService.java

link:complete/library/src/main/java/hello/service/MyService.java[role=include]

To make it configurable in a standard Spring Boot idiom (with application.properties) you can also add a @ConfigurationProperties class:

library/src/main/java/hello/service/ServiceProperties.java

link:complete/library/src/main/java/hello/service/ServiceProperties.java[role=include]

You don’t have to do it this way: a library might just provide pure Java APIs, and no Spring features. In that case the application that consumes the library would need to provide the configuration itself.

Testing the Service Component

You will want to write unit tests for your library components. If you are providing re-usable Spring configuration as part of the library, you might also want to write an integration test, to make sure that the configuration works. To do that you can use JUnit and the @SpringBootTest annotation. For example:

library/src/test/java/hello/service/MyServiceTest.java

link:complete/library/src/test/java/hello/service/MyServiceTest.java[role=include]
Note
In the sample above we have configured the service.message for the test using the default attribute of the @SpringBootTest annotation. It is not advisable to put application.properties in a library because there might be a clash at runtime in the application that uses it (only one application.properties is ever loaded from the classpath). You could put application.properties in the test classpath, but not include it in the jar, for instance by placing it in src/test/resources.

Create an Application Project

Create the directory structure

In a the "application" directory, create the following subdirectory structure; for example, with mkdir -p src/main/java/hello/app on *nix systems:

└── src
    └── main
        └── java
            └── hello
                └── app

Do not use the same package as the library (or a parent of the library package) unless you want to include all Spring components in the library by @ComponentScan by default in the application. Now comes the build configuration:

Gradle Configuration for Application

Gradle Configuration for Application

application/build.gradle

link:initial/application/build.gradle[role=include]

Maven Configuration for Application

Maven Configuration for Application

Write the Application

The main class in the application can be a @RestController that uses the Service from the library to render a message. For example:

application/src/main/java/hello/app/DemoApplication.java

link:complete/application/src/main/java/hello/app/DemoApplication.java[role=include]

Because DemoApplication is inside a different package (hello.app) than MyService (hello.service), @SpringBootApplication won’t detect it initially. There are different ways to allow `MyService to be picked up:

  • Import it directly with @Import(MyService.class).

  • Fetch everything from it’s package using @SpringBootApplication(scanBasePackageClasses={…​}).

  • The method this guide uses—​specifying the parent package by name, hello.

Create the application.properties file

We need to provide a message for the service in the library via application.properties. In the sources folder, you just need to create a file src/main/resources/application.properties:

link:complete/application/src/main/resources/application.properties[role=include]

Test the application

Test the end-to-end result by starting the application. You can start the application in your IDE quite easily, or follow the instructions below to use the command line. Visit the client app in the browser, http://localhost:8080/. There, you should see the String Hello World reflected in the response.

Gradle Command Line to Run Application

Gradle Command Line to Run Application

Build the library first and then run the application. From the top level:

$ ./gradlew build && ./gradlew :application:bootRun

Maven Command Line to Run Application

Maven Command Line to Run Application

Build the library first and then run the application. From the top level:

$ ./mvnw install && ./mvnw spring-boot:run -pl application

Summary

Congratulations! You’ve just used Spring Boot to create a re-usable library, and then used it to build an application.

About

Creating a Multi Module Project :: Learn how to build a library and package it for consumption in a Spring Boot application

http://spring.io/guides/gs/multi-module


Languages

Language:Java 88.6%Language:Shell 11.4%