For every Java developer Hibernate, Spring are everyday terms. Although recently there was an addition to this list of ‘Spring-boot’. Now-a-days Spring Boot is one of the most used open source framework. Hence if you are a java developer you must know about spring boot. In this tutorial we will cover srping boot features in detials.

Spring-boot can be used to create stand-alone and web enterprise applications with minimal effort. The most important part of this framework is that it makes development very convenient by removing lengthy, repetitive boilerplate code and common configuration steps.

Is it worth learning Spring Boot?

Yes, of course. Java is one of the most popular and most used programming language. Java with spring is the most powerful combination. After releasing spring boot it has got even more popularity. Spring boot has made things very easy. So learning spring boot will definitely help.

What is basic requirement to setup a spring boot project?

System Requirements for spring boot project setup are

JavaJava 8 or above
Spring FrameworkSpring Framework 5.2.8.RELEASE or above
Maven Or Gradle Maven 3.3 + Or gradle 6.3+

Things that make Spring boot Awesome!

Reasons why spring boot is most used:

  • Quick and easy Project setup
  • Production ready Spring applications ready in few and easy steps 
  • Easy to understand and develop application
  • Increases productivity-reduce the development time for redundant code
  • Auto configuration is possible
  • Dependency management handled internally
  • Provide opinionated ‘starter’ dependencies to simplify your build configuration

Spring-Boot Features:

  1. Auto dependency management using Spring Boot starters
  2. Application Entry point denoted by @SpringBootApplication
  3. Auto configurations
  4. Component Scan
  5. Externalized Configuration
  6. Out of the box spring data jpa support

1. Auto dependency management using Spring Boot starters:

Any project, even a standalone project, is dependent on some libraries for something. These libraries are available as dependencies/jars. Sometimes it happens that even these libraries are dependent on some other libraries. Most of the times they need specific versions. If the related dependency is missing or versions are not compatible the application does not work as expected.

We cannot deny that managing the dependencies is difficult. Spring boot solves this problem by providing dependency-management section.

Spring boot provides starter packages which includes jars and the required versions, so we do not need this anymore 🙂 . It configures the dependency versions based on the release. If we need specific version we can off course specify the version for dependency, However it is not recommended.

Point to remember is that each version of spring boot has different versions. If we upgrade the Spring Boot version, related dependencies will be upgraded automatically.

All Spring Boot starters are named as spring-boot-starter-[starter-name]
eg: spring-boot-starter-web or spring-boot-starter-data-jpa

You can visit starters list to see all available spring boot startes.

2. Application Entry point denoted by @SpringBootApplication:

For project, as it grows, it is difficult to find out the entry point of the project after some times. As a spring boot application is a java application the entry point is Main method. When we give control to string boot by calling SpringApplication.run method, this main method is found and executed. To run() method we need to pass class name which is the primary component and args array. Primary component is the class with @SpringBootApplication annotation.

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Note that @SpringBootApplication annotation includes @EnableAutoConfiguration, @ComponentScan and @SpringBootConfiguration annotations. That means if we add @SpringBootApplication annotation these annotations will be added automatically.

We can run spring boot application in different ways. 

  • By using IDE as java application
  • Using building tool like maven as mvn spring-boot:run

We should see the starter banner once the application starts. We can also customize spring-boot start up banner.

3. Auto configuration:

One more problem that every developer has faced while developing a project is that of extensive configurations. Configurations for database, flyway, rest API, security etc. are required in any and all applications. These can be sometimes excessive and time consuming.

But spring-boot resolves this situation too. Spring Boot does the configurations automatically according to the dependencies added. For instance, if we add spring-boot-starter-web dependency to our project, then webserver, servlets etc. will be configured automatically.

We must use @EnableAutoConfiguration annotation to infrom srping boot that auto configuration is requried.

Note: As we read earlier, including @SpringBootApplication annotation will include @EnableAutoConfiguration annotation.

4. Component scan:

One of the most important feature of spring is dependency injection. To detect the classes for auto injection, spring uses special stereotype annotations such as @Component, @Controller, @Service, and @Repository.

In order to create objects of these annotated classes and inject them, spring needs to know where they are located. One way to do that is by using @ComponentScan annotation.

In spring boot application @SpringBootApplication annotation adds @ComponentScan annotation with default setting. Hence by default spring boot scans the annotated classes under the current package. Due to this it is recommended that we put our main class in the root or top most package.

We can also override @ComponentScan annotation to specify packages to scan. If we need to scan paths other than the root package. There are many way to do that, some ways are as below,

@ComponentScan("com.stacktrace.guru")
@ComponentScan({"com.stacktrace.guru.package1","com.stacktrace.guru.package2"})

For more details visit : ComponentScan java doc

5. Externalized configuration

Frequently there are scenarios where some data used in an application is different for different environments. Such as, the port number, where the application is deployed is different for development and production environment. In such cases, hardcoding them in the code could be difficult to manage and change.

Spring boot allows multiple options to externalize this properties. We can use these configured properties using the @Value annotation or by binding properties to objects using @ConfigurationProperties.

Configuration properties can be provided using configuraion files,, command line or system setting.

File configuration can be provided by adding files like application.propertiesapplication.yaml or in the classpath. In general src/main/resources directory is used to store configuration files.

application.properties file example

server.port = 8090
spring.application.name = demo-application

application.yaml file example

spring:
    application:
        name: demo-application
    server:
        port: 8090

Note that:

We can also change the configuration file name by using spring.config.name property.

Config file location can be changed using spring.config.location environment property. 

6. Out of the box spring data jpa support:

Spring data jpa is one of the most important support provided by spring boot. Spring boot provides Spring data JPA using hibernate as default JPA provider. These feature can be enabled by adding just spring-boot-starter-data-jpa dependency and by providing database source. 

Spring Data JPA provides repository abstraction, that means we don’t need to worry about writing implementation of repository classes any more. Just adding meaningful method name in interface is enough.

Fast tract reading

  • Spring boot is most used opensource framework by spring community
  • It helps to create production ready project in easy and simple steps
  • Removes repeated and complex processes
  • Increases productivity-reduce the development time 
  • It supports auto dependency management using Spring Boot starters
  • Auto configures most of the things like database, rest API, security etc
  • It comes with by default support for spring data jpa

Related topics

Nowadays spring boot and spring data are widely used frameworks. If you are building web application in java, spring boot is the first choice. If you have Database then spring data JPA is best choice. In spring boot spring data is the default implementation for database interaction. Spring boot using spring data JPA even creates nested object query from method name.

Therefore, if you are using spring boot or spring data JPA, you must know how queries are created specially if you have nested object structure. 

Introduction

Spring data JPA provides repository abstraction and reduces the boiler plate code from persistence layers. As discussed in our previous blog Spring data Java beginner, we can define queries in two ways, Query annotation and Method name itself.

For simple use cases method name for query resolution is best option. However, using spring boot for nested object property without knowing how it works, could cause big issue at runtime.

Lets understand what could be the problem in nested object query and how can we resolve it.

Problem statement

For example if you create method findByDepartmentId, what will be the query? It would be either,

Select * from ClassRoom where departmentId=?

OR

Select * from ClassRoom c left join department d on <condition> where d.id =?

Both are the possibilities depending on the class structure like

Class ClassRoom {
   Long departmentId;
}

Or

Class ClassRoom {
    Department department;
}
Class Department {
    Long id;
}

Then the big question is, what happens when we have following structure?

Class ClassRoom {
    Department department;
    Long departmentId;
}

Confussed face
Class ClassRoom {
    Department department;
    Long departmentId;
}

How spring data resolves method name

Let’s see how spring data jpa in spring boot decides what join should be used to avoid wrong select query.

Consider the object structure as below for these classes : Student- classroom-department

Class Student {
    ...
    ClassRoom classRoom;
}
Class ClassRoom {
    …..
    Department department;
}
Class Department{
    ...
    Long id;
}

We will be using above database structure and try to understand what happens when we create a method findByClassRoomDepartmentId(Long id)

Following are the steps that spring data jpa will perform to create query

  • Start by taking complete name as classRoomDepartmentId under the domain class
  • If this doesnot match split word at camel case part form right side into 2 parts as classRoomDepartment and id
    • Check whether first property matches, take that property and continue for second part- keep building tree
    • If first side does not match, continue to split to next point i.e. classRoom and departmentId
How spring boot resolve nested object query from method name using spring data JPA
Method name to property resolution flow diagram

In most of the cases this works, however this could fail if we have Long classRoomDepartment variable in Student class. JPA will find the first match as classRoomDepartment, it will select and fail because it will try to find id variable inside the classRoomDepartment which is Long class. But as there is no id property inside the Long class and it will fail.

Solution:

To solve such problem, we can use ‘_’ (Underscore) character inside the method name to define where JPA should try to split. In this case our method name will be findByClassRoom_DepartmentId()

Using underscore is not in the java naming best practice, but this is allowed in spring data JPA.

Fast track reading

  • In Spring data Java queries can be defined using Query annotation or Method name
  • For simple cases derived query from method name is best choice
  • We can use method name to derive query for nested object also
  • Spring data jpa starts checking for property from full name and starts breaking at camel case from right to left
  • To avoid the property name confusion ‘_’ (Underscore) character can be used to separate property names

Related topics

Databases form an integral part of computer applications. With it comes considerable amount of database operations and the corresponding code. For huge applications which have large number of tables/entities, these operations or the code is repeated and duplicated to a large extent. Eventually a programmer would like to reduce this duplicate code. Spring framework took up the challenge and provided us with a solution in the form of Spring Data JPA.

Spring Data is one of the most useful feature released by Spring team. JPA stands for Java Persistence API.

Spring Data JPA provides repository abstraction. This means that the common or repetitive code for the repository is generated by Spring data. The programmer need not write that code again and again for all the repositories.
Thus using Spring Data reduces the boilerplate code from persistence layers.

Features of Spring Data can be listed as

  • The Spring Data generates implementation. That means we do not need to implement DAO manually anymore
  • Spring Data JPA reduces the boilerplate code required by JPA
  • That helps to implement persistence layer easier and faster
  • The DAO implementations to be completely removed

Spring Data JPA can be used with a normal Spring application as well as a Spring boot application. We shall look at both ways further in this blog.

4 steps to configure Spring Data JPA:

  1. Extend Repository interface
  2. Declare query methods in the interface
  3. Set up Spring for instantiating these interfaces
  4. Inject these instances for use

1) Extend Repository interface

In order to use Spring data with JPA, our repository or DAO interface must extend JPA specific repository interface.

This will enable Spring data to find our interface and automatically create implementation for it. Thus, our DAO interface can extend Repository interface, JpaRepository interface or any of its sub interface.

Extending sub interface indirectly extends Repository interface.

The Repository interface is the most important interface in Spring Data. It is marker interface. Repository interface takes Domain class and id type as generic type arguments.

Syntax: public interface Repository<T, ID>

T- Domain type, ID- id data type

Example for use of Repository interface

interface StudentRepository extends Repository<Student, Long> { … }

There are some sub interfaces provided by spring data for additional functionalities. Some of the sub interfaces are,

  • public interface CrudRepository<T, ID>: It provides basic CRUD functionalities.
    eg: interface StudentRepository extends CrudRepository<Student, Long> { … }
  • public interface PagingAndSortingRepository<T, ID>: this interface provides paging and sorting functionalities in addition to CRUD operations.
    eg: interface StudentRepository extends PagingAndSortingRepository <Student, Long> { … }

2) Declare query methods on the interface

Once we have created the interface for our entity, it’s time to create methods. As discussed, Spring data JPA has a feature that implements repository methods for us. All we have to do is tell Spring data what methods we need.

2 ways to define method in spring data JPA

  1. By deriving the query from the method name 
  2. Manual query using “@Query” annotation

2.1) By deriving the query from the method name

It is as straight forward as the name suggests. All we need to do is, name the method in such a way that it tells what exactly the method wants.

For instance, If we want to fetch data for the Student with department id.
The corresponding method name will be like, 

List<Student> findByDepartmentId(Long departmentId);

As we can see that the method is in plain English and easy to understand.

Assume a Student has a Department object. In Department we have id. In that case, the method creates the property traversal student.department.id.

This method will create following query

select * from Student where departmentId = ?1;

In general our interface will look like below,

interface StudentRepository extends Repository<Student, Long> {
   List<Student> findByDepartmentId(Long departmentId);
}

For this purpose, Spring data has reserved some key words such as, the prefixes find_By, read_By, query_By, count_By, and get_By in the method.

We can also use the keywords such as AND and OR to create qurey with multiple properties of an entity. We also get support for operators such as Between, LessThan, GreaterThan, and Like for the property expressions.

These supported operators can vary by database of choice. So consulting the appropriate part of reference documentation is advised. You can read more at keywords in spring data.

2.2) Manual query using “@Query” annotation

Using meaningful method name for repository sounds very interesting, however sometimes that is not enough. Specially if we need multiple properties in queries or complex query.

We can create method but the name of the method can be very long.

List<Student> findByFirstNameAndLastNameOrderByFirstnameAsc(String firstName,String lastName);

In such cases we can use @query annotation provided by Spring Data. 

@Query("SELECT s FROM Student s WHERE s.firstName =?1 or s.lastName =?2 order by firstName asc)")
List<Student> findByName(String firstName,String lastName);

Using position based parameter (?paramPosition) could be difficult to understand and refactor. This can be avoided by using named-parameters in query. We can use “:paramName” and “@Param” annotation for parameter binding.

@Query("SELECT s FROM Student s WHERE s.firstName = :firstName or s.lastName = :lastName order by firstName asc)")
List<Student> findByName(@Param("firstName")String firstName, @Param("lastName")String lastName);

3) Configuration for spring data JPA

Spring Data JPA can be used in basic spring or spring-boot project. Also the configuration can be done using xml or java classes. For configuration using java class, we need to use @Configuration annotation.

3.1 Spring data JPA configuration in spring boot:

Spring boot is another very famous framework, which make application creation and management very fast and easy. It has auto configuration feature which provides all required dependencies and configuration. We just need to add correct dependencies.

It also auto configures Spring data and hibernate as default JPA. Also it provides all necessary configuration required for spring data according to database used. We just need to add correct database connector dependency and provide data source.

We don’t need to do other configuration unless, we need to customize it.

Spring boot configuration using application.properties

spring.datasource.url=jdbc:mysql://localhost:3306/database_name
spring.datasource.username=root 
spring.datasource.password=root

3.2 Spring data JPA configuration in non-spring boot:

To use spring data we need to configure following objects:

  1. DataSource: Database configuration- URL, username, password, driver, etc
  2. EntityManager: Most important object which binds all objects, like entity package, datasource, etc
    1. we can configure entityManager using LocalEntityManagerFactoryBean
    2. we can also configure additional properties using setJpaProperties(properties)
  3. TransactionManager: Configuration for database transaction
Configuration using java code:
@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
class ApplicationConfig {

  @Bean
    public DataSource dataSource(){
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/database_name");
        dataSource.setUsername( "root" );
        dataSource.setPassword( "root" );
        return dataSource;
    }

  @Bean
  public LocalContainerEntityManagerFactoryBean entityManagerFactory() {

    JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
    LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
    entityManager.setJpaVendorAdapter(vendorAdapter);
    entityManager.setPackagesToScan("com.entity.package");
    entityManager.setDataSource(dataSource());
    return entityManager;
  }

  @Bean
  public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
    JpaTransactionManager txManager = new JpaTransactionManager();
    txManager.setEntityManagerFactory(entityManagerFactory);
    return txManager;
  }
}
Configuration using xml file:

Similar to java code we can configure all necessary objects in xml file

<bean id="entityManager" 
 class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="dataSource" ref="dataSource" />
    <property name="packagesToScan" value="com.entity.package" />
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" /> 
   </property>
 </bean>

<bean id="dataSource" 
  class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="url" value="jdbc:mysql://localhost:3306/database_name" />
    <property name="username" value="root" />
    <property name="password" value="root" />
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManager" />
</bean>

<tx:annotation-driven />
<bean id="persistenceExceptionTranslationPostProcessor" class= 
"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />

4) Inject the repository instance for use

Once all the above steps are done we are ready to use. Now we just need to instantiate and use use the interfaces.

We can do that using spring basic features like dependency injection using @Autowired annotation.

class StudentService{ 

@Autowired 
private final StudentRepository studentRepository;
  
  public List<Student> findByDepartmentId(Long departmentId) {
    return studentRepository.findByDepartmentId(departmentId);
  }
} 

Fast track reading

  • Spring Data JPA is one of the most useful feature released by Spring team
  • Using Sping data JPA repository implementation can be completely removed
  • Can be used with core spring or spring boot application
  • Should extend  JPA specific Repository interface or it’s sub interface
  • Required method can be declared using meaningful name or using @Query annotation
  • Configuration can be done using xml file or in java code

Related topics

Whenever we start a Spring Boot application a text message shown below is displayed . This is called as a banner.

spring boot startup banner

Now, wouldn’t it be wonderful if we could create a custom banner which is specific to our Spring Boot application and use it instead of default Spring Boot banner.

There are many ways to generate and use spring boot custom banner.

We will cover following topics in detail,

  1. Custom spring boot banner generator and generation
  2. Configure spring boot application to use custom banner
  3. Disable spring boot banner

1. Custom spring boot banner generator and generation

For showing the custom banner at application startup we need a banner.
We can create custom banner by our self in text file, can create programatically or use various online free tools.
We can have banner in plain text file by using the Ascii charters or in image format.

The banner in the plain text format is faster to load and easier to maintain. So in this blog we will be using text banner but you can use as per your choice.

1.1 Spring boot custom banner online generator:

There are so many Ascii banner generator tools are available online like,

1.2 Programmatic banner generation:

Spring boot framework provides a Banner interface that allows us to create banners.
We need a class that implements Banner interface and overrides printBanner() method for configuring custom banner.

import java.io.PrintStream;
import org.springframework.boot.Banner;
import org.springframework.core.env.Environment;
public class CustomBanner implements Banner {
	@Override
	public void printBanner(Environment arg0, Class<?> arg1, PrintStream arg2) {
		arg2.println("###############################");
		arg2.println("###### Spring boot banner ######");
		arg2.println("###############################");
	}
}

The most important thing to note is that, the banner configured in printBanner() method will only be used if we do not have configured banner in properties or banner file.

In the banner, we can use following placeholders for dynamic values.

VariableDescription
${application.version} Displays application version number
e.g. 1.0
${application.formatted-version}Displays application version number with bracket and v
e.g. (v1.0)
${spring-boot.version} Displays Spring Boot version
e.g. 2.2.7.RELEASE
${spring-boot.formatted-version}Displays Spring Boot version with bracket and v
e.g. (v2.2.7.RELEASE)
${application.title}Displays application titleas declared in MANIFEST.MF.
e.g. MyApp.

2. Configure spring boot application to use custom banner

After the banner is generated, we need to make it available for application to use.
By default spring boot uses file named banner.txt or banner.(png|jpg|gif) in the src/main/resources directory.

We can store at this location the file with name banner.txt.
We can also store in different location with any file name.

If we decide to store in other than src/main/resources/banner.txt, we need to configure the file location so that application can use it.

2.1 We can configure using following properties:

spring.banner.image.location=classpath:custom-banner.png
spring.banner.location=classpath:/path/bannerfile.txt

2.2 Configure banner by a program:

We can configure banner in SpringApplication class using setBanner() method.

@SpringBootApplication
public class BootApplication {  
    public static void main(String[] args) {
	SpringApplication application = new SpringApplication(BootApplication.class);
	application.setBanner(new CustomBannner());
	application.run(args);
    }
}

3. Disable spring boot banner

If you don’t want the banner it is also possible to disable the banner.
In spring boot, we can disable the banner using configuration file or via a program.

Disabling banner using configuration file is the most flexible and recommended way as is easier and can be reverted easily if required.

3.1 Disable using configuration file:

Spring boot supports multiple ways to configure the application. Like using application.properties, application.yaml file.

3.1.1 Disable banner using application.properties file:

If we add following line to application.properties file the startup banner will be disabled

spring.main.banner-mode=off

3.1.2 Disable banner using application.yaml file:

If we add following lines to application.yaml file the startup banner will be disabled

spring:
  main:
    banner-mode:"off"

3.2. Disable banner from application code:

In spring boot code we can configure application using SpringApplication or SpringApplicationBuilder. We can also use java 8 features lambda expression in sring boot application.

3.2.1 Disable banner using the SpringApplication:

SpringApplication app = new SpringApplication(MyApplication.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);

3.2.2 Disable banner using the SpringApplicationBuilder:

new SpringApplicationBuilder(MyApplication.class)
    .bannerMode(Banner.Mode.OFF)
    .run(args)

Fast track reading

  • Banner is a fancy text message displayed at spring boot application start up
  • We can create custom banner our self or generate using online free tools
  • Banner can be in a text or image format
  • Text format banner is faster to load
  • Spring boot banner can have placeholders for dynamic values
  • We can also disable spring boot banner

References:

Other Topics