Introduction to Boot2.0 Chapter 16 Deployment, Testing and Monitoring

  • JUnit testing, use of Mockito


  • After creating the directory with war, the IDE will help to generate the required directory for the web application
    • webapp directory
    • Also add something to pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="" xmlns:xsi=""


	<description>chapter15 project for Spring Boot</description>

		<relativePath /> <!-- lookup parent from repository -->







  • mvn package
  • java -jar spring-0.0.1-snapshot.war
  • java -jar spring-0.0.1-snapshot.war --server.port=9080
  • To use a third-party non-embedded server, you need to initialize the Dispatcher yourself

    public class ServletInitializer extends SpringBootServletInitializer {
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    		return application.sources(Chapter15Application.class);
    • mvc provides the implementation class of ServletContainerinitializer: SpringServletContainerInitializer
    • This class: It will traverse the implementation class of the WebApplicationInitializer interface.
    • Among them: SprigBootServletInitializer is its implementation class
  • Just copy xxx.war to the webapps directory of tomcat.

hot deployment

  • true dependencies will not be passed, other projects depend on the current project, and this hot deployment will not take effect on this project.
  • Hot deployment is passed, and LiveReload supports it.
  • Hot deployment There are many configurations, see for yourself


  • Support Jpa, MongoDB, Rest, Redis
  • Mock test
@RunWith(SpringRunner.class) //The loaded class is the operation of Spring combined with JUnit

//Start the test service with a random port. Configure Test Related Features
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)

public class Chapter16ApplicationTests {

	// Inject the user service class
    private UserService userService = null;

    public void contextLoads() {
        User user = userService.getUser(1L);
        // Determine if user information is empty
 // REST test template, provided automatically by Spring Boot
    private TestRestTemplate restTemplate = null;

    // Test get user function
    public void testGetUser() {
        // Request the currently started service, note the URI abbreviation
        User user = this.restTemplate.getForObject("/user/{id}",
                User.class, 1L);
    private ProductService productService = null;

    public void testGetProduct() {
        // Build dummy objects
        Product mockProduct = new Product();
        mockProduct.setProductName("product_name_" + 1);
        mockProduct.setNote("note_" + 1);
        // Specify Mock Bean methods and parameters
                // Specifies the returned virtual object
        // Mock test
        Product product = productService.getProduct(1L);
        Assert.assertTrue(product.getId() == 1L);


	public Product getProduct(Long id) {
		throw new RuntimeException("Failed to support this method");

mock test

  • During testing, use a dummy object to create a test method for testing
  • getProduct(1L) currently cannot schedule product microservices, mock can give a virtual product
  • @MockBean Mock test for that bean

actuator monitoring endpoint

  • hateoas is a complex constraint in the REST architectural style, a dependency for building mature REST services.

actuator endpoint description

  • health
  • httptrace latest trace information (100 by default)
  • info
  • mappings all mapping paths
  • scheduledtasks shows scheduled tasks
  • shutdown

http monitoring

  • http://localhost:8080/actuator/health
  • http://localhost:8080/actuator/beans needs to be enabled
  • Default values ‚Äč‚Äčexpose info and health
# Expose all endpoints info,health,beans

#Do not expose this endpoint

# By default all endpoints are not enabled, in this case you need to enable endpoints on demand
# enable endpoint info
# Enable endpoint beans
# Actuator endpoint prefix

View sensitive information

  • The above is fully exposed, very incomplete
@SpringBootApplication(scanBasePackages = "com.springboot.chapter16")
@MapperScan(basePackages = "com.springboot.chapter16", annotationClass = Mapper.class)
public class Chapter16Application extends WebSecurityConfigurerAdapter {

    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // password encoder
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // use memory storage
                // Set password encoder
                // Register the user admin, the password is abc, and give the role permissions of USER and ADMIN
                // The encrypted password can be obtained by passwordEncoder.encode("abc")
                .password("$2a$10$5OpFvQlTIbM9Bx2pfbKVzurdQXL9zndm1SrAjEkPyIuCcZ7CqR6je").roles("USER", "ADMIN")

                // connection method and

                // Register the user myuser, the password is 123456, and give the role permission of USER
                // The encrypted password can be obtained by passwordEncoder.encode("123456")

    protected void configure(HttpSecurity http) throws Exception {
        // Endpoints that need Spring Security protection
        String[] endPoints = {"auditevents", "beans", "conditions", "configprops", "env", "flyway",
                "httptrace", "loggers", "liquibase", "metrics", "mappings", "scheduledtasks",
                "sessions", "shutdown", "threaddump"};

        // Define the endpoints that need to be authenticated
        // http.requestMatcher(

                // Request to close page requires ROLE_ADMIN orange


                // Start HTTP Basic Authentication

    public static void main(String[] args) {, args);


.authorizeRequests().anyRequest() //After signing in

shutdown endpoint

<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <!-- load Query document-->
    <script src=""></script>
    <script type="text/javascript">
        $(document).ready(function () {
            $("#submit").click(function () {
                // request shutdown endpoint
                    url: "./actuator/shutdown",
                    // method after success
                    success: function (result) {
                        // Check request result
                        if (result != null || result.message != null) {
                            // print message
                        alert("closure Spring Boot Application failed");
    <title>test close request</title>
<input id="submit" type="button" value="close the app"/>

public class CloseController {
	public ModelAndView close(ModelAndView mv) {
		// Define the view name as close and let it jump to the corresponding JSP
		return mv;

Configure endpoints


# expose all endpoints

# management.endpoints is public

# By default all endpoints are not enabled, in this case you need to enable endpoints on demand

# enable endpoint info

# Enable endpoint beans

# enable config endpoint

# start env

# enable health

# enable mappings

# enable shutdown

# Actuator endpoint prefix

# Modify the request path of the original mapping endpoint to urlMapping
  • http://localhost:8000/manage/health

                    "message":"The current server has access to the World Wide Web."

custom endpoint

// Let Spring scan the class
// define endpoints
		// endpoint id
		id = "dbcheck",
		// Whether the endpoint is enabled by default
		enableByDefault = true)
public class DataBaseConnectionEndpoint {
	private static final String DRIVER = "com.mysql.jdbc.Driver";
	private String url = null;
	private String username = null;

	private String password = null;

	// An endpoint can only have one method annotated with @ReadOperation
	// It represents an HTTP GET request
	public Map<String, Object> test() {
		Connection conn = null;
		Map<String, Object> msgMap = new HashMap<>();
		try {
			conn = DriverManager.getConnection(url, username, password);
			msgMap.put("success", true);
			msgMap.put("message", "Test database connection is successful");
		} catch (Exception ex) {
			msgMap.put("success", false);
			msgMap.put("message", ex.getMessage());
		} finally {
			if (conn != null) {
				try {
					conn.close(); // close database connection
				} catch (SQLException e) {
		return msgMap;

{"success":true,"message":"Test database connection is successful"}

Custom World Wide Web Health Metrics

http://localhost:8080/manage/health has been accessed above

// The monitoring server is capable of accessing the World Wide Web
public class WwwHealthIndicator extends AbstractHealthIndicator {
	// By monitoring Baidu server, see if you can access the Internet
	private final static String BAIDU_HOST = "";
	// overtime time
	private final static int TIME_OUT = 3000;

	protected void doHealthCheck(Builder builder) throws Exception {
		boolean status = ping();
		if (status) {
			// The health indicator is available and a message item is added
			builder.withDetail("message", "The current server has access to the World Wide Web.").up();
		} else {
			// The health indicator is no longer in service, and a message item is added
			builder.withDetail("message", "The World Wide Web is currently unavailable").outOfService();

	// Monitoring Baidu server access to determine whether access to the World Wide Web
	private boolean ping() throws Exception {
		try {
			// When the return value is true, the host is available, and false is not.
			return InetAddress.getByName(BAIDU_HOST).isReachable(TIME_OUT);
		} catch (Exception ex) {
			return false;


JMX monitoring


Select: org.springframework.boot—endpoint—health—click health

Tags: Testing monitor and control

Posted by xkaix on Wed, 01 Jun 2022 01:10:03 +0530