Spring boot project structure

Keywords: Programming Spring Java Maven xml

Using Spring Boot

Spring Boot project can be downloaded directly from start.spring.io

| 
|   pom.xml
|           
|           
\---src
    +---main
    |   +---java
    |   |   \---com
    |   |       \---zdx
    |   |           \---readinglist
    |   |                   ReadingListApplication.java
    |   |                   
    |   \---resources
    |       |   application.properties
    |       |   
    |       +---static
    |       \---templates
    \---test
        \---java
            \---com
                \---zdx
                    \---readinglist
                            ReadingListApplicationTests.java

View the Initialization Spring Book New Project

  • The directory structure follows the layout of traditional Maven projects
  • The main application code is located in src/main/java
  • Resource files are located in src/main/resources
  • The test code is in src/test/java
  • If there are test resources, they should be in src/test/resources.

Main documents:

  • ReadingListApplication.java application bootstrap class is also the main Spring configuration class.
  • application.properties are used to configure properties of applications and Spring Boot s.
  • ReadingList Application Tests. Java is a basic integration test class.

Start boot Spring

ReadingListApplication.java has two roles in Spring:

  1. To configure
  2. Boot boot

Although Spring Boot's automatic configuration eliminates many Spring configurations, you still need to make a few configurations to enable automatic configuration.

By default, there is only one line of configuration code:

package com.zdx.readinglist;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
//Open component scanning and automatic configuration
public class ReadingListApplication {

    public static void main(String[] args) {
        //Responsible for launching boot application
        SpringApplication.run(ReadingListApplication.class, args);
    }

}
  • @ Spring Boot Application opens Spring's component scanning and Spring Boot's automatic configuration capabilities, but in fact @SpringBoot Application combines three useful annotations:
    • @ Configuration indicates that this class uses Spring Java-based configuration...
    • @ ComponentScan enables component scanning so that custom Web controller classes and other components are automatically discovered and registered as beans in the Spring application context
    • @ Enable AutoConfiguration is also known as @Abracadabra: This line of configuration opens Spring Boot automatic configuration

Before Spring Boot 1.2.0, you need to mark all three annotations on the startup class at the same time.

Configure the properties of the application

The application.properties file generated by default is an empty file

If application.properties exist, they will be loaded without specifying

application.properties use examples:

server.port=8000

With this line, the embedded Tomcat listening port becomes 8000

Analysis of Spring Boot Project Construction Process

Spring Boot provides build plug-ins for Gradle and Maven to help build Spring Boot projects.

Selecting Maven will generate a pom.xml file for you, using Spring Boot's Maven plug-in

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--from spring-boot-starter parent Inheritance Version Number-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.7.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.zdx</groupId>
    <artifactId>readinglist</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Reading List</name>
    <description>Reading List Demo</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <!-- Start Dependence -->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <!--Application Spring Boot Plug-in unit-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

  • The main function of building plug-ins is to package the project into an executable super JAR (uber-JAR), which includes putting all the dependencies of the application into the JAR file and adding a description file for the JAR, which allows you to run the application with java-jar.

  • In addition to building plug-ins, spring-boot-starter-parent is also used as the upper level, so that Maven's dependency management function can be used to inherit dependency versions of many common libraries, so you don't need to specify the version number when you declare dependencies. Note that there is no specified version of dependency in this pom.xml

Start Dependence

First of all, assuming there is no start dependency, with Spring MVC, we know the following points:

  1. Which Spring dependencies do you need?
  2. Thymeleaf Group and Artifact ID
  3. Which version of Spring Data JPA to use
  4. Compatibility issues

This is just to develop a Spring Web application that uses the Thymeleaf view to persist data through JPA. But before we tap into the code, we need to understand what we need to add to POM.XML to support our project.

There may be the following:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>2.1.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
         <version>2.1.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
        <version>2.1.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.1.7.RELEASE</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <version>2.1.7.RELEASE</version>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.17</version>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>2.1.7.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <version>5.1.6.RELEASE</version>
        <scope>test</scope>
    </dependency>
</dependencies>

This dependency list is good and should work, but what do you know? We still have a long way to go before we start building without writing a single line of code?

  • Let's step back and think about what we're going to do. We want to build an application with the following functions.
    • This is a Web application.
    • It uses Thymeleaf
    • It persists data in relational databases through Spring Data JPA

Wouldn't it be simpler if we only specified these functions in the build file so that the build process could figure out what we wanted for itself? This is what Spring Boot relies on to start with.

Transfer dependencies introduced by coverage start dependencies

Take Spring Boot's Web Start Dependency as an example, which delivers dependencies on Jackson JSON libraries. If you are building a REST service that produces or consumes JSON resource representations, it will be useful. However, to build traditional human-oriented Web applications, you may not need Jackson. Although it won't do any harm to add it in, you can lose weight for your project by eliminating its transmission dependency.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.fasterxml.jackson.core</groupId>
        </exclusion>
    </exclusions>
</dependency>

On the other hand, maybe the project needs Jackson, but you need to build it with another version of Jackson, not the one in the Web Start Dependency. Suppose the Web Start Dependency refers to Jackson 2.3.4, but you need to use 2.4.3. In Maven, you can express your appeal directly in pom.xml, just like this:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.4.3</version>
</dependency>

Use automatic configuration

When Spring Boot is added to an application, there is a JAR file called spring-boot-autoconfigure, which contains many configuration classes. Each configuration class is in the application's Classpath and has the opportunity to contribute to the application's configuration. These configuration classes have configurations for Thymeleaf, Spring Data JPA, Spiring MVC, and many other things that you can choose to use in Spring applications.

All these configurations are so different because they take advantage of Spring's conditional configuration, a new feature introduced by Spring 4.0. Conditional configurations allow configurations to exist in applications, but they are ignored until certain conditions are met.

In Spring, you can easily write your own conditions. All you have to do is implement the Condition interface and override its matches() method. For example, the following simple conditional class will only take effect if JdbcTemplate exists in Classpath.

public class JdbcTemplateCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        try {
            context.getClassLoader().loadClass("org.springframework.jdbc.core.JdbcTemplate");
            return true;
        } catch (ClassNotFoundException e) {
            return false;
        }
    }
}

When you declare beans in Java, you can use this custom condition class:

@Conditional(JdbcTemplateCondition.class)
public MyService myService() {
    ...
}

In this example, the MyService Bean is created only when the condition of the JdbcTemplateCondition class holds. That is to say, MyService Bean is created on the condition that there is JdbcTemplate in the Classpath. Otherwise, the bean declaration will be ignored.

These configuration classes constitute the automatic configuration of Spring Boot. Spring Boot uses conditional configuration by defining several special conditional annotations and applying them to configuration classes

Conditional annotation Configuration Effective Conditions
@ConditionalOnBean Configured a particular Bean
@ConditionalOnMissingBean No specific Bean is configured
@ConditionalOnClass Classpath has a specified class
@ConditionalOnMissingClass Lack of specified classes in Classpath
@ConditionalOnExpression The result of a given Spring Expression Language (SpEL) expression is true
@ConditionalOnJava Java version matches a specific value or a range value
@ConditionalOnJndi A given JNDI location in a parameter must exist, and if no parameter is given, there must be a JNDI Initial Context.
@ConditionalOnProperty The specified configuration property must have a clear value
@ConditionalOnResource Classpath has specified resources
@ConditionalOnWebApplication This is a Web application
@ConditionalOnNotWebApplication This is not a Web application

Posted by wanda46 on Thu, 05 Sep 2019 22:09:50 -0700