How Spring Boot tests packaged deployments

Keywords: Programming Spring Java Tomcat Maven

I. Development Phase

(1) Unit testing

The most important thing in the development phase is unit testing, and Spring Boot's support for unit testing is already complete.

1. Add dependencies to the pom.xml file

<dependency>
    <groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>

2. Develop Test Classes

For the simplest example of helloworld, add @RunWith(SpringRunner.class) and @SpringBootTest annotations to the class header of the test class, add @Test to the top of the test method, and right-click run on the method to run.

@RunWith(SpringRunner.class)
@SpringBootTest
public class ApplicationTests {
	@Test
	public void hello() {
		System.out.println("hello world");
	}
}

In practice, you can inject data-tier code or service-tier code for test validation according to the normal use of the project. spring-boot-starter-test provides many basic usages, but more rarely, it adds support for controller-tier testing.

//Simple validation of the result set
Assert.assertEquals(3,userMapper.getAll().size);

//Validate result set, promote
Assert.assertTrue("Error, correct return value is 200",status==200);
Assert.assertFalse("Error, correct return value is 200",status!=200);

MockMvc was introduced to support testing the controller layer, with the following simple examples:

public class HelloControlerTests {

    private MockMvc mvc;

    //Initialization Execution
    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.standaloneSetup(new HelloController()).build();
    }

    //Verify that the controller responds properly and print the returned results
    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
                .andExpect(MockMvcResultMatchers.status().isOk())
                .andDo(MockMvcResultHandlers.print())
                .andReturn();
    }
    
    //Verify that the controller responds properly and determine if the results are correct
    @Test
    public void testHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Hello World")));
    }

}

Unit testing is the first barrier to validating your code. To get into the habit of unit testing every part of your code you write, don't wait until all the integrations have been completed. After integration, bug s at the bottom of your code can easily be omitted because you focus more on overall performance.

(2) Integration testing

Enter integration testing after the overall development is complete. The startup entry of Spring Boot project is in the application class. Run the run method directly to start the project, but during the debugging process we must constantly debug the code. If you need to start the service manually every time you modify the code, Spring is a problem.Boot is very thoughtful in providing hot deployment support for debugging in web projects.

Add a dependency to pom.xml:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
            <configuration>
                <fork>true</fork>
            </configuration>
        </plugin>
</plugins>
</build>

With these configurations added, the project supports hot deployment, making it easy to integrate tests.

2. Online

In fact, I think this stage should be relatively simple, generally divided into two types, one is packaged into jar packages to execute directly, the other is packaged into war packages to put under tomcat server.

(1) Packaging into jar packages

If you are using maven to manage your project, execute the following command

cd Items and directories (and pom.xml Peer)
maven clear package
//Or execute the following command
//Package after excluding test code
mvn clean package -Dmaven.test.skip=true

After packaging, jar packages are generated into the target directory, usually named Project Name + version number.jar

Launch jar package command

java -jar target/spring-boot-scheduler-1.0.0.jar

In this way, as long as the console is closed, the service is inaccessible.Here's how we start in the background:

nohup java -jar target/spring-boot-scheduler-1.0.0.jar &

You can also choose to read different profiles at startup

java -jar app.jar --spring.profiles.active=dev

You can also set jvm parameters at startup

java -Xms10m -Xmx80m -jar app.jar &

If you are using gradle, use the following command to package

gradle build
java -jar build/libs/mymodule-0.0.1-SNAPSHOT.jar

(2) Packaging Wars

There are two ways to make a war package. The first way is to export a war package through eclipse, a development tool, and the other way is to use commands. The second way is mainly described here.

1. maven project, modify pom.xml

<packaging>war</packaging>

2. Exclude tomcat when packaging

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-tomcat</artifactId>
	<scope>provided</scope>
</dependency>

Set the scope property to provided here so that the jar package will not be included in the final formed war because servers such as tomcat or jetty will provide the associated API classes at runtime.

3. Register Startup Class

Create ServletInitializer.java, inherit SpringBootServletInitializer, override configure(), and register the startup class Application.When an external Web application server builds a Web Application Context, the startup class is added.

public class ServletInitializer extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }
}

Final Execution

mvn clean package  -Dmaven.test.skip=true

Generated in the target directory: project name + version number.war file, copy to tomcat server to start.

If you're using Gradle, just like the basic steps, build.gradle adds war support, excluding spring-boot-starter-tomcat:

...

apply plugin: 'war'

...

dependencies {
    compile("org.springframework.boot:spring-boot-starter-web:1.4.2.RELEASE"){
    	exclude mymodule:"spring-boot-starter-tomcat"
    }
}
...

Reuse the build command

gradle build

Wars are generated in the build\libs directory.

3. Production, operation and maintenance

1. View the values of JVM parameters

You can use the jinfo command that comes with java:

jinfo -flags pid

To see what gc, new generation, and older generation batched memory jar uses after it starts, an example is as follows:

-XX:CICompilerCount=3 -XX:InitialHeapSize=234881024 -XX:MaxHeapSize=3743416320 -XX:MaxNewSize=1247805440 -XX:MinHeapDeltaBytes=524288 -XX:NewSize=78118912 -XX:OldSize=156762112 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseParallelGC

-XX:CICompilerCount: Maximum number of parallel compilations

-XX:InitialHeapSize and -XX:MaxHeapSize: Specify the initial and maximum heap memory size of the JVM

-XX:MaxNewSize:Maximum allocatable size of new generation memory in the JVM heap area

-XX:+UseParallelGC: Garbage Recycling Using Parallel Collector

2. How to restart

(1) kill the process directly and start the jar package again

ps -ef|grep java 
##Get pid for Java program
kill -9 pid
## Restart again
Java -jar  xxxx.jar

Of course, this way is more traditional and violent, so we recommend that you use the following ways to manage it

(2) Script execution

If you are using maven, you need to include the following configuration

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
        <executable>true</executable>
    </configuration>
</plugin>

If using gradle, you need to include the following configuration

springBoot {
    executable = true
}

Startup mode:

  • You can start it directly. /yourapp.jar
  • Register as Service

You can also make a link to your jar package, add it to init.d, and start it with a command.

init.d example

ln -s /var/yourapp/yourapp.jar /etc/init.d/yourapp
chmod +x /etc/init.d/yourapp

This allows you to use the stop and restart commands to manage your applications.

/etc/init.d/yourapp start|stop|restart

perhaps

service yourapp start|stop|restart

Now that you have finished testing, aligning, and bundling for this Spring Boot project, you can explore the automated operation and maintenance of spring boot and the use of a combination of spring boot and docker.

 

More exciting content, the first public number, [Su Xiao Nuan], welcomes your attention.

Posted by boo_lolly on Sun, 23 Feb 2020 18:56:52 -0800