Spring Boot Web Application – Part 1 – Spring Initializr
15 CommentsSpring Boot – Making Spring Fun Again
I’ve been playing around with Spring Boot again and really like what The Spring Team has been doing. Spring Boot is making Spring fun again. I haven’t had this much pleasure developing Spring Applications since I started learning Grails.
One of the things I loved about the Grails framework was its common sense approach to building web applications. Sure, Spring was under the covers of Grails. But the Grails team wired Spring up with a lot of defaults. For example, if you were using Hibernate to write to a database, of course, you’re going to want a Spring Transaction Manager.
Grails came out of the box with a transaction manager configured for you. If you were writing a Spring MVC application, you’d need to add a transaction manager into your configuration. The Spring Framework gives you all these pre-built components, but it was left up to you to wire them up into your application. You as the developer are responsible for everything. All the components are there, but some ‘assembly’ is required.
The cool part about Spring Boot is it makes a lot of common sense guesses for you. Like if you add Hibernate to your build, it guesses you’re going to want a transaction manager. The transaction manager is just one example of a common no-brainer Spring component you’d normally need to wire up that Spring Boot will automatically do for you. Spring Boot actually has over 200 default choices which it makes for you.
Spring Boot takes a lot of the mundane pain out of building Spring Applications. It really is making Spring Fun again. Spring Boot is still a newcomer in the family of Spring Projects. Even though Spring Boot is new, I think its the future of Spring application development.
Building a Spring Boot Web Application
Think about building a simple web application using Spring. You’re probably going to want to:
- Use Spring of course!
- Spring MVC for the web part.
- Thymeleaf for the template engine, because you’re just plain tired of using JSPs.
- Good ol’ Hibernate for your ORM.
- An H2 database as your development database.
- Spring Data to take the pain out of using Good Ol’ Hibernate.
- Spring Security to secure your web application.
- Tomcat as your application server.
In this Spring Boot tutorial, I’m going to walk you through step by step in developing a web application using Spring Boot and the technologies I listed above.
Getting Started with Spring Boot
I already created one ‘Getting Started with Spring Boot‘ post, but I’m going to walk through another example here. I want you to be able to follow through this Spring Boot tutorial step by step.
Creating the Spring Boot Project Using IntelliJ
The folks over at JetBrains have added some awesome support for Spring Boot in IntelliJ. This makes it very easy to create a Spring Boot based project using the IntelliJ IDE.
In the following video, I show you how to initialize a Spring Boot project with IntelliJ.
If you don’t have access to IntelliJ, you can always use the Spring Initializr to download a preconfigured Spring Boot project. Be sure to check the following options:
- Security
- Thymeleaf
- Web
- JPA
- H2
Reviewing the Spring Initializr Artifacts
The project created by the Spring Initializer is a Maven project and follows the standard Maven directory layout. Below is a screen print from my IntelliJ IDE. There is one application class created for us, an empty properties file, a stub for a JUnit integration test, and the Maven POM file.
SpringBootWebApplication.java
The Spring Initializer create us a very basic Spring Boot application class. Technically, this is a Spring Configuration class. The annotation @SpringBootApplication
enables the Spring Context and all the startup magic of Spring Boot.
package guru.springframework; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootWebApplication { public static void main(String[] args) { SpringApplication.run(SpringBootWebApplication.class, args); } }
SpringBootWebApplicationTests.java
We also give a stub of a JUnit Integration test. Check out this post if you’d like to learn more about Integration Testing with Spring and JUnit.
package guru.springframework; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.web.WebAppConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest(classes = SpringBootWebApplication.class) @WebAppConfiguration public class SpringBootWebApplicationTests { @Test public void contextLoads() { } }
pom.xml
Here is the Maven POM file that the Spring Initializer created for us. This was customized for us based on the options we selected in the Spring Initializer. The presence of these dependencies is important because Spring Boot will make decisions on what to create automatically when certain things are found on the classpath. For example, you can see the dependency for the H2 database. Because this exists on the classpath when the application is run, Spring Boot will automatically create a data connection and an embedded H2 database.
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>guru.springframework</groupId> <artifactId>spring-boot-web</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>Spring Boot Web Application</name> <description>Spring Boot Web Application</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <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> <!--WebJars--> <dependency> <groupId>org.webjars</groupId> <artifactId>bootstrap</artifactId> <version>3.3.4</version> </dependency> <dependency> <groupId>org.webjars</groupId> <artifactId>jquery</artifactId> <version>2.1.4</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
Spring Boot Dependencies
What I found interesting about Spring Boot is how it manages dependencies. In the early days of Java development, you as the developer were required to manage all the dependencies. It was a very time-consuming task. And led to a lot of errors. If you were using an open source library in your project, it was very easy to forget one of its dependencies, which could lead to runtime errors. In modern Java development, this task of dependency management has been delegated to tools such as Maven.
Now when you define dependency in Maven, Maven checks that artifacts dependencies, each of which can have its own set of dependencies, and so on. You can read more about dependency management in Maven here.
I’m impressed with how the Spring Boot team has leveraged the dependency management features of Maven (and Gradle) for Spring Boot. Prior to Spring Boot, when setting up a Spring Project, you needed to compose the Spring jars needed for your project. This was not always as straight forward as it sounds. The Spring Boot team has basically created Spring Boot POMs with bundled Spring dependencies.
You can use the Maven command of mvn dependency:tree
to generate a report on the dependency tree. Running the command on this project produces the following dependency tree.
[INFO] guru.springframework:spring-boot-web:jar:0.0.1-SNAPSHOT [INFO] +- org.springframework.boot:spring-boot-starter-data-jpa:jar:1.4.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.4.2.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot:jar:1.4.2.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-autoconfigure:jar:1.4.2.RELEASE:compile [INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.4.2.RELEASE:compile [INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.7:compile [INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.7:compile [INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.21:compile [INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.21:compile [INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime [INFO] | +- org.springframework.boot:spring-boot-starter-aop:jar:1.4.2.RELEASE:compile [INFO] | | \- org.aspectj:aspectjweaver:jar:1.8.9:compile [INFO] | +- org.springframework.boot:spring-boot-starter-jdbc:jar:1.4.2.RELEASE:compile [INFO] | | +- org.apache.tomcat:tomcat-jdbc:jar:8.5.6:compile [INFO] | | | \- org.apache.tomcat:tomcat-juli:jar:8.5.6:compile [INFO] | | \- org.springframework:spring-jdbc:jar:4.3.4.RELEASE:compile [INFO] | +- org.hibernate:hibernate-core:jar:5.0.11.Final:compile [INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile [INFO] | | +- org.hibernate.javax.persistence:hibernate-jpa-2.1-api:jar:1.0.0.Final:compile [INFO] | | +- org.javassist:javassist:jar:3.20.0-GA:compile [INFO] | | +- antlr:antlr:jar:2.7.7:compile [INFO] | | +- org.jboss:jandex:jar:2.0.0.Final:compile [INFO] | | +- dom4j:dom4j:jar:1.6.1:compile [INFO] | | | \- xml-apis:xml-apis:jar:1.4.01:compile [INFO] | | \- org.hibernate.common:hibernate-commons-annotations:jar:5.0.1.Final:compile [INFO] | +- org.hibernate:hibernate-entitymanager:jar:5.0.11.Final:compile [INFO] | +- javax.transaction:javax.transaction-api:jar:1.2:compile [INFO] | +- org.springframework.data:spring-data-jpa:jar:1.10.5.RELEASE:compile [INFO] | | +- org.springframework.data:spring-data-commons:jar:1.12.5.RELEASE:compile [INFO] | | +- org.springframework:spring-orm:jar:4.3.4.RELEASE:compile [INFO] | | +- org.springframework:spring-context:jar:4.3.4.RELEASE:compile [INFO] | | +- org.springframework:spring-tx:jar:4.3.4.RELEASE:compile [INFO] | | +- org.springframework:spring-beans:jar:4.3.4.RELEASE:compile [INFO] | | +- org.slf4j:slf4j-api:jar:1.7.21:compile [INFO] | | \- org.slf4j:jcl-over-slf4j:jar:1.7.21:compile [INFO] | \- org.springframework:spring-aspects:jar:4.3.4.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter-security:jar:1.4.2.RELEASE:compile [INFO] | +- org.springframework:spring-aop:jar:4.3.4.RELEASE:compile [INFO] | +- org.springframework.security:spring-security-config:jar:4.1.3.RELEASE:compile [INFO] | | \- org.springframework.security:spring-security-core:jar:4.1.3.RELEASE:compile [INFO] | \- org.springframework.security:spring-security-web:jar:4.1.3.RELEASE:compile [INFO] | \- org.springframework:spring-expression:jar:4.3.4.RELEASE:compile [INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:1.4.2.RELEASE:compile [INFO] | +- org.thymeleaf:thymeleaf-spring4:jar:2.1.5.RELEASE:compile [INFO] | | \- org.thymeleaf:thymeleaf:jar:2.1.5.RELEASE:compile [INFO] | | +- ognl:ognl:jar:3.0.8:compile [INFO] | | \- org.unbescape:unbescape:jar:1.1.0.RELEASE:compile [INFO] | \- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:jar:1.4.0:compile [INFO] | \- org.codehaus.groovy:groovy:jar:2.4.7:compile [INFO] +- org.springframework.boot:spring-boot-starter-web:jar:1.4.2.RELEASE:compile [INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:1.4.2.RELEASE:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:8.5.6:compile [INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:8.5.6:compile [INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:8.5.6:compile [INFO] | +- org.hibernate:hibernate-validator:jar:5.2.4.Final:compile [INFO] | | +- javax.validation:validation-api:jar:1.1.0.Final:compile [INFO] | | \- com.fasterxml:classmate:jar:1.3.3:compile [INFO] | +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.4:compile [INFO] | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.4:compile [INFO] | | \- com.fasterxml.jackson.core:jackson-core:jar:2.8.4:compile [INFO] | +- org.springframework:spring-web:jar:4.3.4.RELEASE:compile [INFO] | \- org.springframework:spring-webmvc:jar:4.3.4.RELEASE:compile [INFO] +- org.webjars:bootstrap:jar:3.3.4:compile [INFO] +- org.webjars:jquery:jar:2.1.4:compile [INFO] +- com.h2database:h2:jar:1.4.193:compile [INFO] +- org.postgresql:postgresql:jar:9.4-1206-jdbc42:compile [INFO] \- org.springframework.boot:spring-boot-starter-test:jar:1.4.2.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test:jar:1.4.2.RELEASE:test [INFO] +- org.springframework.boot:spring-boot-test-autoconfigure:jar:1.4.2.RELEASE:test [INFO] +- com.jayway.jsonpath:json-path:jar:2.2.0:test [INFO] | \- net.minidev:json-smart:jar:2.2.1:test [INFO] | \- net.minidev:accessors-smart:jar:1.1:test [INFO] | \- org.ow2.asm:asm:jar:5.0.3:test [INFO] +- junit:junit:jar:4.12:test [INFO] +- org.assertj:assertj-core:jar:2.5.0:test [INFO] +- org.mockito:mockito-core:jar:1.10.19:test [INFO] | \- org.objenesis:objenesis:jar:2.1:test [INFO] +- org.hamcrest:hamcrest-core:jar:1.3:test [INFO] +- org.hamcrest:hamcrest-library:jar:1.3:test [INFO] +- org.skyscreamer:jsonassert:jar:1.3.0:test [INFO] | \- org.json:json:jar:20140107:test [INFO] +- org.springframework:spring-core:jar:4.3.4.RELEASE:compile [INFO] \- org.springframework:spring-test:jar:4.3.4.RELEASE:test [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 38.431 s [INFO] Finished at: 2016-12-06T19:57:37+05:30 [INFO] Final Memory: 22M/133M [INFO] ------------------------------------------------------------------------
Here you can see how the top level Spring Boot starter dependencies listed in the Maven POM file call in their respective Spring components. Its a very simple idea, but very useful too. In days past, I can remember whenever starting a new Spring project spending a morning or so mucking around setting up the Maven Dependencies for the Spring components I was using.
Free Introduction to Spring Tutorial
Conclusion
In this post we’ve taken a look at using the Spring Initializer via IntelliJ to create a Spring Boot Project and examined the project files created by the Spring Initializer.
If you watched the video of me trying to run the Spring Boot application in IntelliJ, you saw the application fail because there were not Thymeleaf templates. In the next post of this tutorial series on Spring Boot, I’ll show you how to set up the Web Assets.
Get The Code
I’ve committed the source code for this post to github. It is a Maven project which you can download and build. If you wish to learn more about the Spring Framework, I have a free introduction to the Spring tutorial. You can sign up for this tutorial in the section below.
The source code for this post is available on github. You can download it here.
Marvin
Why the spring initializer not creating webapp folder?
jt
Its not needed.
Albe
Hello,nice post , I reach out with you because I want to know if is possible have in the same project two database, for example PostgreSQL for the production environment and h2 only for testing , so the classes Test only connect to h2 database, so with the test cases you never change the production environment .Please let me know if you have any example .
Regards
jt
Yes – that is a fairly common use case. See this post: http://springframework.guru/using-h2-and-oracle-with-spring-boot/
Albe
Thanks Guru
Akash Sharma
Hi JT, Guru, this article was very informative and a starter like me felt very comfortable with the way information was provided.
In short a great and helpful tutorial indeed. Thank you.
jt
Thanks!
Prathamesh Mantri
Hi JT,
Do you have starter steps for Spring Boot application using weblogic server?
jt
No – been some time since I used WebLogic. Good luck!
vinayak
how to run the project?