Spring WebApplicationInitializer

Spring WebApplicationInitializer

In this article, we will get an understanding of  Spring WebApplicationInitializer interface along with a detailed analysis of the benefits and configurations of Spring WebApplicationInitializer.

 

Introduction

Dispatcher Servlet is known as an entry point for Spring MVC based web applications, you can think of Dispatcher Servlet as a gatekeeper for MVC application responsible to understand the request, send it to correct place and responsible to send the response back to the calling party.

Spring 3.1 Brough support for the Servlet 3 API, before that we can only register Servlet Dispatcher with Servlet container via the standard Web application web.xml file.

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
	http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">

    <display-name>Spring3 MVC Application</display-name>

    <servlet>
        <servlet-name>spring-web</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>spring-web</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

With Spring support for Servlet 3.0 Specification, web.xml is optional and we can manage all our web application using Java Annotations.

One of the natural questions will arise in your mind is “If we are not registering Dispatcher Servlet than how Spring will create/bootstrap Dispatcher Servlet for our application?

Spring WebApplicationInitializer is the answer to your above question which was introduced with Spring 3.1.

 

1. What is Spring WebApplicationInitializer?

Spring WebApplicationInitializer is Servlet 3.0 + implementation to configure ServletContext programmatically in comparison to the traditional way to do this using web.xml.

 

2. Hybrid Configuration

We have 2 ways to replace traditional web.xml using Spring WebApplicationInitializer, in this one we will discuss a mix of replacing configuration using Java Annotation and XML based Spring configuration.

public class CustomWebAppInitializer implements WebApplicationInitializer {
    /**
     * Configure the given {@link ServletContext} with any servlets, filters, listeners
     * context-params and attributes necessary for initializing this web application. See examples
     * {@linkplain WebApplicationInitializer above}.
     *
     * @param servletContext the {@code ServletContext} to initialize
     * @throws ServletException if any call against the given {@code ServletContext} throws a {@code
     *                          ServletException}
     */
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        XmlWebApplicationContext applicationContext = new XmlWebApplicationContext();
        applicationContext.setConfigLocation("location of spring config xml file");

        //Dispatcher servlet configuration

        ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(applicationContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }

Above approach looks good, clean and preferred way to do it but this is not purely Java code based approach as we are still using web.xml in our code to read this configuration.

 

3. WebApplicationInitializer With Java Annotation

Let’s change our previous code to purely Java Annotation-based configuration.We will try to use Spring @Configuration classes in place of traditional XmlWebApplicationContext.

public class CustomWebAppInitializer implements WebApplicationInitializer {
    /**
     * Configure the given {@link ServletContext} with any servlets, filters, listeners
     * context-params and attributes necessary for initializing this web application. See examples
     * {@linkplain WebApplicationInitializer above}.
     *
     * @param servletContext the {@code ServletContext} to initialize
     * @throws ServletException if any call against the given {@code ServletContext} throws a {@code
     *                          ServletException}
     */
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {

        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.register(Application.class);

        // Manage the lifecycle of the root application context
        servletContext.addListener(new ContextLoaderListener(rootContext));

        // Register and map the dispatcher servlet
        ServletRegistration.Dynamic dispatcher =
                servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");
    }
}

 

Let’s try to understand above example for better clarity.

As we are using Java-based annotation in place for XML configuration, we are going to use AnnotationConfigWebApplicationContext for this

AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

We need to register our context, this can be easily done by registering our custom configuration class.

rootContext.register(Application.class);

Let’s say your custom configurations are spread across multiple classes and you want to use all of these configurations, Spring WebApplicationInitializer provide a way to specify root package to be scanned for configuration classes.

rootContext.setConfigLocation("com.javadevjournal.app.config");

the application context is in place now, next step is to add our ContextLoaderListner to the ServletContext which will be responsible to load the context

// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));

The final step of our example is creating and registering Dispatcher servlet, which is the entry point of our application.

// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
        servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
 
3.1 Web.xml and Java Annotation Caveats

Please be aware of the fact that web.xml and Spring WebApplicationInitializer configurations are not mutually exclusive, this means you can register one servlet in your application’s web.xml while you can use WebApplicationInitializer to register another servlet for your application.In case you have a web.xml file under WEB-INF/web.xml, it’s version must be set to 3.0 or greater else ServletContainerInitializer will completely ignore your web.xml file.

 

Annotation-based configurations offer a lot of advantages and these configurations are now becoming de facto standards for the new Spring-based applications, annotations are more concise and they normally add clear context to the declaration, however, there are certain cases where this is not a preferred way 

  • I still want to separate out my code and configurations
  • Any third party solution which is outside of our control and we can not customize it.

 

Summary

In this article, We got an understanding of  Spring WebApplicationInitializer interface. we covered traditional way to initialize our Spring application. We covered mix way (use configuration and annotation) for our application configuration. In the last part, we covered the new way (100% java base) configuration.

Spring WebApplicationInitializer is really powerful and with new Servlet 3.0 specification, it provides a more flexible way to configure our application. In the next article, we will be covering web.xml and Initializer in more detail.

Functional Interfaces in Java 8

Functional Interfaces in Java 8

This post works as an introduction to the Functional Interfaces in Java 8. We will be covering some of the basics of the Functional Interfaces introduced in Java 8.

 

Introduction

Java has always been called as OOP (Object Oriented Programming) language. Functions do not exist independently in Java and everything is part of Class and use to class/object to invoke any function (ie, JNI). Functional Programming Language is written independent functions and uses them when required such as C++, JavaScript.

Function Interface was introduced in Java8 as new features along with Stream API, Time API, Lambda Expression, etc., Function Interface having only one abstract method which means interface contains only one abstract method and it can have multiple default methods.

 

1.FunctionalInterface Example 

@FunctionalInterface annotation was introduced along with other annotation in Java 8 which can be used to validate at the compile time that can’t have more than one method beside default.

Let’s create a simple example to understand few details of the @FunctionalInterface.

@FunctionalInterface
public interface Account {

    int returns();

    default void printDetails() {
        System.out.println("Default Methods");
    }
}

An interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface’s abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere (ie., abstract methods that override the method in the object).

@FunctionalInterface
public interface Account {

    int returns();

    default void printDetails() {
        System.out.println("Default Methods");
    }

    /*
     * Overridden from Object class
     */
    public String toString();

    public int hashCode();

}

FunctionalInterface annotation is not mandatory to use because of the compiler will treat any interface meeting the definition of a functional interface as a functional interface regardless of whether or not a FunctionalInterface annotation is present on the interface declaration.

Java earlier version having a single abstract method in the interface and they were known as simple abstract method interface e.g.,Runnable Interface (Run method), Comparator Interface.

 

2.Functional Interfaces Type 

The declaration of a functional interface allows a functional interface type to be used in a program by the developer and these are segregated as four kinds of functional interface type based on a declaration.

 

Another interesting part is Interface can extend another interface and In this scenario, Interface extending in functional and it doesn’t declare any new abstract methods then the new interface is functional which will satisfy the definition.

public interface Bank {

    public void openAccount();
}

Account interface extends Bank interface which has only one OpenAccount method and Account interface doesn’t have any abstract method but still, it is valid functional Interface.

@FunctionalInterface
public interface Account extends  Bank {}

Let see one more example, consider while inherits two abstract which have the same signature.

public interface SocialMedia {
  public void OpenAccount();
}

In this case, still, the inherited methods logically represent a signal method so Account is a function interface.

@FunctionalInterface
public interface Account extends SocialMedia {
}

 

Consider above example, if one is return type substitutable then Account causes compile time error because it’s inheriting two methods.

 

interface Bank {public void OpenAccount();}
interface SocialMedia {public boolean OpenAccount();}

There are numbers of functional interfaces defined under java.util.function package, some of the useful interfaces are

  • Consumer
  • Function
  • Supplier
  • Predicate

 

2.1  Predicate Example

import java.util.function.Predicate;;

/**
 * @author Arunchandu
 */
public class PredicateTestExample {

    public static void main(String[] args) {

        Predicate<String> i = (name) -> name.contains("java");
        System.out.println(i.test("Thank you for Learning from javadevjournal.com"));
    }

}

 

2.2  Pass Function Example

import java.util.function.Function;

public class PassFunction {

    public static void main(String[] args) {
        int percentage = 5;
        String result = calc((amount) -> "Tax : " + ((amount * 100) / percentage), 10);

        System.out.println(result);

    }

    public static String calc(Function<Float, String> bi, float i) {
        return bi.apply(i);
    }

}

 

Summary

In this post, we got an introduction to the Functional Interfaces in Java 8. We covered some of the aspects of functional interfaces along with few interesting functional interfaces introduced in Java 8.

If you are starting with Java 8, read our following articles on Java 8

  1. Introduction to Java 8 Streams
  2. java 8 optional
  3. Java 8 StringJoiner

Introduction to Java 8 Streams

Introduction to Java 8 Streams

In this post, we will get a quick Introduction to Java 8 Streams API, a new feature introduced in Java 8.We will try to get a high level of understanding as what is stream and how this can be used in our day to day work.

 

Introduction

Streams are one of the most important APIs introduced in Java 8 and completely changes the way we do processing of Collections in Java. This is in line with the theme of Java since past few versions where advances in hardware are exploited by the language.

 

1. Why Java 8 Streams

Before diving into ‘What’ of Streams, let us get into ‘Why’. Why were Streams introduced and what
problem they solve?

Let us see the code below:

private static HashMap<String, Integer> myIterator(List<String> inList) {
    Iterator<String> thisIterator = inList.iterator();
    HashMap<String, Integer> map = new HashMap<String, Integer>();
    while (thisIterator.hasNext()) {
        String str = thisIterator.next();
        if (str.length() > 5) {
            map.put(str, str.length());
        }
    }
    return map;

}

Above code is not doing anything fancy or complicated but it takes in a List of String, calculates the length of each String in List and puts the String, String Length in a HashMap if length greater than 5. It is definitely solving our problem but there are multiple problems with above code.

  1. The code is sequential in nature and in spite of my computer being a Quad core system, I am not exploiting computer’s processing power here.
  2. Simply, too much code for a simple task.
  3. As a programmer, I need to work on the lower level aspects of the program. I have to take care of ‘how’ the iteration takes place apart from the program logic. Such programmer driven iteration is called External Iteration. It can have optimization issues in complex and data-intensive programs.

 

2. Code Simplifaction using Java Streams

Java Streams help us address the above-mentioned issues by completely abstracting out the low-level parallelism logic and Iteration logic.Putting in the most simple way, Java Streams convert Collections to a Stream, process the elements in parallel by performing multiple operations and again gather the final elements into a Collection.

Java Stream API helps us do above mention by implementing internal iteration. It lets the framework perform a sequential and parallel execution, mapping elements and criteria based filtering. Java framework is in control of the resulting iteration and lets the developer fully concentrate on the data and various operations to be performed on it.

Java Stream API implements functional interfaces as its API methods, which ties up well with Lambda expressions, which is another pillar of Java 8. Together they make the Java 8 a true ‘functional’ language.

Thus, when we use Java Streams, the code mentioned above turns into a single line code.


private static Map<String, Integer> myIterator(List<String> inList) {

    return inList.stream().filter(str -> str.length() > 5).
            collect(Collectors.toMap(str -> str, str -> str.length()));
}

Here inList is a List of Strings. Stream method takes the inList and streams it into a filter. Filter passes only those Strings which meet the criteria (String.length>5). Collect method takes in the filtered Strings and sends them to Collector.toMap() function which inserts the String and their Lengths in the Map.

In a single line of code, we utilize the Streaming, Filtering and Collection mechanisms of the API thus writing a more efficient code.

 

3. Steams API Benefits

let’s see other important aspects of Streams.

Streams are on-demand Data Structures. They don’t store data and instead take in a Data Structure(mainly Collections) as the source to produce a pipeline of that Collection. On this pipeline, desired functions can be called further to harness the power of in-memory computation.

Streams support Parallel Processing and Sequential Processing both, giving the developer options to use whatever mechanism as per the requirement. For large collections, Parallel Processing can work wonders in terms of achieving great performance.

Streams support Lazy computation, that means we do these operations only when we need it and not when they are defined in the Streams.This leads to higher performance and optimization of the programs than the traditional methods.

Streams have two types of Operations: Intermediate and Terminal. All those Stream operations which return a new Stream are called intermediate operations. These never return the final result of the operations and help in building a pipeline from one operation to another. filter and map are two such operations.

All Stream operations which return a result are Terminal operations. They are eager computations which process Stream elements before returning results and they consume the Stream. After consumption by these operations, Streams are no more available for further processing. They can be identified by their return types as they would not produce any further Streams. Examples are:forEach, toArray, min, max etc.

 

Summary

This was a very high level and a brief Introduction to Java 8 Streams API. We discussed what are the benefits and features brought by Java Streams and how they can be utilized to write more concise and easily readable code.

Stay tuned to our website for further content on Streams and other in-depth content in Java.If you are interested to learn about new features of Java 8, read 

Java 8 optional

Java 8 StringJoiner

Spring Framework Annotations

 Introduction to Spring Framework Annotations

In this post, we will get a quick introduction to Spring Framework Annotations. We will explore different annotations along with few of the internal details for these Spring Framework Annotations.

 

Introduction

Java 5.0 introduced support for the annotations and very quickly it became one of the preferred ways, Spring Framework was quick to adopt this and with 2.5 Spring Framework started support for annotations.

Though we can still use XML based configurations to control/manage our Spring application, Spring Framework Annotations are now becoming a defacto standard for Spring-based enterprise applications.

 

1. Spring Core Annotation

In this section, we will be covering Spring Framework Core Annotations.

1.1 @Required

@Required annotation is applied to the bean setter method to enforce require property.It can be used when we want to make sure that a specific bean is required to be injected by Spring, in case required Spring bean is unable to inject the required bean, BeanInitializationException is thrown.

@Required
public void setClient(OkHttpClient client) {
    this.client = client;
}

 

1.2 @Autowired

@Autowired annotation is used to inject object implicitly, We can apply this annotation to fields, setter methods, and constructors.

You can use @Autowired annotation on the constructor, Spring will inject dependency at the time of object creation. Please note that you can only use this annotation to the maximum of 1 constructor for a given class.

@Autowired
public WebConfiguration(RequestResult result){
    this.requestResult=result
}

For @Autowire annotation, Spring does not have the requirement for the constructor to be public.

We can also use @Autowire annotation on the class property 

@Autowired
private OkHttpClient client;

@Autowired
private ObjectMapper jacksonObjectMapper;

The third option is to use this annotation on the setter method, Spring internally will try to perform injection by Type.

@Autowired
public void setClient(OkHttpClient client) {
    this.client = client;
}

With Spring 4.3, @Autowire has become optional on classes with a single constructor, so for the below code, Spring will try to inject instance of the Customer (even we do not have @Autowire annotation)

@Component
public class Customer {
    
   private Order order;

    public Customer(Order order) {
        this.order = order;
    }
}

 

1.3 @Qualifier

When you need more control over the dependency injection process, you should consider using @Qualifier annotation.The qualifier annotation helps disambiguate bean references when Spring would otherwise not be able to do so, in short, this annotation is used to avoid confusion in the dependency injection.

To understand it more clearly, let’s take a simple example of HelloWorldService, let’s assume that we have 2 implementations of our HelloWorldService

public interface HelloWorldService {
    
    void sayHello();
}

public class HelloWorldService1 implements  HelloWorldService {
    
    @Override
    public void sayHello() {
        
    }
}

public class HelloWorldService2 implements  HelloWorldService {
    
    @Override
    public void sayHello() {
        
    }
}

In case we want to Inject our HelloWorldService1 using @Autowire annotation, Spring will not know which one of the two implementations to inject.

public class HelloWordTest {
    
    @Autowired
    private HelloWorldService helloWorldService;
}

To handle all similar issues where we want to let Spring know about which dependency to pick and inject, we can use @Qualifier annotation.

@Autowired
@Resource(name = "helloService1")
private HelloWorldService helloWorldService;

 

1.4 @Bean

@Bean annotation is used to create bean in the Spring Framework, this annotation is used at the method level

@Bean
public Customer customer() {
    // instantiate and configure customer obj
    return customer;
}

By default,  strategy for determining the name of a bean is to use the name of the @Bean method, however, if we want to explicitly name our bean, we can always use “name” or “alias” value to do that.

@Bean({"user", "customer"})
public Customer customer() {
    // instantiate and configure customer obj
    return customer;
}

 

1.5 @Configuration

This annotation is used at the class level which defines Beans, think of @Configuration annotation as configuration using Java class (than traditional XML file to define Spring Beans)

@Configuration
public class ApplicationConfig {
  
    @Bean
    public OkHttpClient client(){
        return new OkHttpClient.Builder()
                .build();
    }

   @Bean
    public CommonsRequestLoggingFilter requestLoggingFilter() {
        CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
        loggingFilter.setIncludeClientInfo(true);
        loggingFilter.setIncludeQueryString(true);
        loggingFilter.setIncludePayload(true);
        loggingFilter.setIncludeHeaders(false);
        return loggingFilter;
    }
}

 

1.6 @ComponentScan

This annotation is used to configures component scanning directives for use with @Configuration classes, we can specify base package from where we want Spring to scan packages.If specific packages are not defined, scanning will occur from the package of the class that declares this annotation.

 

1.7 @Lazy

Spring by default use eager initialization strategy i.e all autowired dependencies will be created and configured at startup.If we do not want this to happen, we can use @Lazy annotation to ensure he @Bean or @Component will not be initialized until referenced by another bean or explicitly retrieved from the enclosing BeanFactory.

@Configuration
@Lazy
public class AppConf {

    @Bean
    public MyBean bean() {
        return new MyBean();
    }

    @Bean
    public MyBean1 bean1() {
        return new MyBean1();
    }

    //Bean2 will be eagerly loaded by Spring
    @Bean
    @Lazy(value = false)
    public Bean2 bean2() {
        return new Bean2();
    }
}

 

1.8 @Value

This is at the field or method/constructor parameter level that indicates a default value expression for the affected argument. This is very similar to @Autowire annotation but @Value annotation will be used to inject values from properties.

To understand it more clearly, let’s take an example where we want to get some of the values from the property file, Let’s define our property file

user.name=Java Dev Journal
language=java

Here is our Java code

@Value("user.name")
private String username;

@Value("language")
private String language;

Please read @ConfigurationProperties in Spring Boot to understand how it works for Spring Boot.

 

In this section, we will be covering Stereotype Annotations provided by Spring Framework.

 

1.9 @Service

This is a class level annotation indicates that an annotated class is a "Service", Apart from the fact that it is used to indicate that it’s holding the business logic, there’s no noticeable specialty that this annotation provides.

@Service("helloService")
public class HelloWorldService1 implements  HelloWorldService {

    @Override
    public void sayHello() {

    }
}

 

1.10 @Repository

This annotation is used on the classes which are working directly with the DB layer, @Repository annotation indicates that an annotated class is a "Repository".One of the different thing being performed by classes annotated with @Repository annotation is to catch Platform specific exceptions and re-throw them as one of Spring’s unified unchecked exception.

 

1.11 @Component

This annotation is used to indicate a Spring-powered component.This is a general-purpose stereotype annotation indicating that the class is a spring component.If we check definitions of @Service or @Repository annotations

@Component
public @interface Service {
   //
}

@Component
public @interface Repository {
   //
}

we can safely say that @Service or @Repository annotations are special kinds of @Component annotation.

 

Summary

In this post, we get an introduction to Spring Framework Annotations. We checked a different kind of  Annotations provided by Spring Framework with information about when to use these Annotations.

In the next article, we will cover some of the important Annotations provided by Spring Boot and Spring MVC framework.

Spring Boot Logging

Introduction to Spring Boot Logging

Logging is one of the important features of any enterprise application, in this post we will get an understanding of Spring Boot Logging mechanism along with few of configuration details.

 

Introduction 

Spring Boot comes with many ready to use features and Logging is one of those features, by default Spring Boot use Commons Logging for its internal logging but it also provides options to use/configure any other log mechanism.

If we are using Spring Boot Starters for our application, Logback will be used for logging by default unless we want to use any other logging API.

 

1.  Understand Log Output

Before we get into more details, let’s take a quick look at the default log out for the Spring Boot application to understand it more clearly.

2017-11-07 20:26:37.317  INFO 5388 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot[email protected]53404716: startup date [Tue Nov 07 20:26:34 PST 2017]; root of context hierarchy
2017-11-07 20:26:37.404  INFO 5388 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/],methods=[GET || POST]}" onto public java.lang.String com.umesh.rest.web.controller.DemoController.sayHello(javax.servlet.http.HttpServletRequest) throws java.io.IOException
2017-11-07 20:26:37.407  INFO 5388 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/demo/greeting],methods=[GET]}" onto public java.lang.String com.umesh.rest.web.controller.LoggingDemoController.sayHello()
2017-11-07 20:26:37.409  INFO 5388 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-11-07 20:26:37.410  INFO 5388 --- [  restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)

There are certain things to understand above log output

  • Date and Time: First section indicates date and time of the log output. (e.g. 2017-11-07 20:26:37.317)
  • Log Level: Second main output indicated log level (e.g. INFO in our case).
  • Number as third output indicates process id (e.g. 5388)
  • — indicated separator
  • Output enclosed in [] indicates Thread name.
  • Last 2 output indicates Logger Name / Log Class name and logs message.

 

2.  Example

To understand how to configure and control Spring Boot Logging, let’s create a simple Controller with few log statements in it.


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@Controller public class LoggingDemoController {
    
 private final Logger log = LoggerFactory.getLogger(this.getClass());
 
 @GetMapping("/demo/greeting") public String sayHello() {
  log.info("Info log statement for LoggingDemoController");
  log.warn("Warn log statement for LoggingDemoController");
  log.error("Error log statement for LoggingDemoController");
  return "greeting";
  
 }
 
}

On running above application by opening http://localhost:8080/demo/greeting, we can see following output in the console.

2017-11-07 20:43:41.566  INFO 5430 --- [io-10070-exec-4] c.u.r.w.c.LoggingDemoController          : Info log statement for LoggingDemoController
2017-11-07 20:43:41.567  WARN 5430 --- [io-10070-exec-4] c.u.r.w.c.LoggingDemoController          : Warn log statement for LoggingDemoController
2017-11-07 20:43:41.567 ERROR 5430 --- [io-10070-exec-4] c.u.r.w.c.LoggingDemoController          : Error log statement for LoggingDemoController

Spring Boot Logging API provides a number of features which help us to decouple out code

  • We are using SFL4J facade for our logging thus we are decoupled from underlying Logback API.
  • By using it, we are free to replace Logback with any other logging API without changing our code base.

 

3.  Log File Output

by default, Spring Boot Logging API will log output to the console and not to any file, for writing log output to a file, we can set logging.file or logging.path property in the application.properties file.

logging.file =/work/demo/log/loggingdemocontroller.log
//or
logging.path= /work/demo/log

Please note that if in case we use logging.path property, Spring Boot will write a file with a name spring.log to the specified directory.

 

4.  Setting Log Levels

Spring Boot provides an easy way to configure and set logging levels for your application.We can use application.properties file to configure the desired Logging level for our application by using ‘logging.level.*=LEVEL’. Let’s use our previous example to get an understanding of setting log level in our application. We will configure our log level to output only WARN and ERROR logs.

application.properties

logging.level.com.javadevjournal.rest= WARN

On running above application by opening http://localhost:8080/demo/greeting, we can see following output in the console.

2017-11-08 20:05:13.362  WARN 8647 --- [nio-8080-exec-1] c.j.r.w.c.LoggingDemoController          : Warn log statement for LoggingDemoController
2017-11-08 20:05:13.362 ERROR 8647 --- [nio-8080-exec-1] c.j.r.w.c.LoggingDemoController          : Error log statement for LoggingDemoController

Since we configured our log level to the WARN, Spring Boot Logging API will only output log statements for WARN and higher (in our case WARN and ERROR).

The root logger can be configured using logging.level.root.

 

5.  Configure Logback Through External File.

For most of the applications, Spring Boot Logging default configurations are more than sufficient, however, for large-scale enterprise applications have complex logging requirements and Spring Boot provide a way to configure it through the external XML file.

You can put logback.xml or logback-spring.xml file in the root of your classpath it will be picked up from there by Spring Boot. Please note that logback-spring.xml is preferred over the logback.xml file by Spring Boot.

here is a sample logback-spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="com.javadevjournal.rest" level="WARN" additivity="false">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
    </logger>
</configuration>

If you want to get more understanding of the System properties which the LoggingSystem takes care of creating for us, please have a look at base.xml file inside spring-boot jar and especially the following line 

<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}}/spring.log}"/>

 

6. Spring Boot Profiles in Logging

Spring Profiling is an excellent concept which provides us the flexibility to define properties for the different environment without any code change. Spring Boot provides the same profile mechanism for the logback configuration by using the <springProfile> element. Let’s use an example to understand how you can define different logging level for DEV and Production environments using the same logback configuration.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <springProfile name="dev">
        <logger name="com.javadevjournal.rest" level="DEBUG" additivity="false">
            <appender-ref ref="CONSOLE" />
        </logger>>
    </springProfile>
    <springProfile name="production">
        <logger name="com.javadevjournal.rest" level="WARN" additivity="false">
            <appender-ref ref="FILE" />
        </logger>
    </springProfile>
 </configuration>

Read Spring Profiles to get an understanding of how to use Spring Profiles feature for your application. 

 

7. Configure Log4j

Not all application want to use default logging configuration and it holds true for Spring Boot Logging mechanism, however, Spring Boot provides an easy way to use any other logging framework.In case you want to use Log4j2 for logging configuration, all you have to add the log4j2 starter in your application (no other complex configurations).

Please be aware that if If you are using the starters for your application, you need to exclude logback and then include log4j 2 instead.

Here is a sample configuration to use log4j for your application.

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

 

Summary 

In this post, we explored different features of the Spring Boot Logging API, we discussed what are the default configurations provided by Spring Boot along with options to configure or customize these options.

Logging is one of the main tool in the application development and with complex enterprise applications, logging requirement can become very complex with the time, however, Spring Boot Logging API provides all the tools to handle all these complex use cases with minimal configuration changes.

If you are starting with Spring Boot, please read Building an Application with Spring Boot to start your journey with Spring Boot

Math.pow in Java

Using Math.pow in Java

In this quick post, we will get an understanding of Using Math.pow in Java. power of the number in a very simple term indicates as to how many times to use a number for multiplication.

 

1.  Example

Math.pow have a very simple signature like

public static double pow(double a, double b), where 'a' indicates the base,  'b' indicated the exponent and Math.pow() will return the value as 

ab

Let’s look into a very simple example to understand how Mah.pow works.

@Test
public void calculateIntPow(){
    int a= 3;
    int b=4;

    int result = (int) Math.pow(a,b);

    assertEquals(81, result);
}

Since we were expecting results in an int, it was required to cast the output to int to get desired results.We are not required to cast results in case desired output is in double (which is also output for  of the Math.pow() method)

@Test
public void calculateDoublePow(){
    double a= 3.4;
    int b=4;

    double result =  Math.pow(a,b);

    assertEquals(133.63, result, 2);
}

There are certain features/properties of this method, read  Math.pow for more detail.

Summary

In this quick post, we get an understanding as to how to Use Math.pow method in Java to calculate the power of any given base.

Initializing Arrays in Java

Initializing Arrays in Java

In this post, we will cover different options for Initializing Arrays in Java along with main differences with each option.

 

Introduction

In this post, we will be covering some of the commonly used ways for Initializing Arrays in Java, we will also discuss briefly these different options and subtle differences between them.

 

1. Initializing using Loop

One of the simplest ways is to initialize an array using a loop, this method will fill one element at a time in the Array.

for( int i=0; i< length ; i++){
    data[i] = i;
}

 

2. Initializing During Declaration

If we know about the size and element of the array, we can also initialize it at the declaration time.

int[] data = {101,201,130,401,350,660,771,880,890,891};

int[] data;
data = new int[] {100,200,300,400,500,600,710,800,900,912};

String[] strings = new String[] {"Sunday", "Monday","Tuesday"};

Please be aware the with above syntax, you will not be able to initialize after this, the system will be throwing a compile-time error if we will try to do this.

 

3. Arrays.fill()

Arrays class contains various methods for manipulating arrays, we can use any of the Arrays.fill() method to fill given the array with the same value.

long array[] = new long[15];
Arrays.fill(array, 20);

There are multiple variations of the fill method which can be used based on the requirement.

 

4. Arrays.setAll()

These methods set all elements of the specified array, using the provided generator function to compute each element.

int[] arr = new int[10];
Arrays.setAll(arr, (index) -> 1 + index);

 

Summary

In this short post, we covered different options to Initializing Arrays in Java. These are handy techniques and commonly used in the day to day development.

Log Incoming Requests In Spring

How to Log Incoming Requests In Spring

In this post, we will explore as of how to Log Incoming Requests In Spring. We will explore different options to accomplish it along with the build in feature provided by Spring.

 

1. Introduction

Having the ability to log incoming request in a web application is a very common requirement for modern web applications.In this article, we will be covering how to do it using Spring’s logging filter.

 

2. Dependency Management

In order to add required logging dependencies, we can add spring-core, for this article, we will be using Spring Boot which will handle dependency management for us. Checkout Building an Application with Spring Boot to learn about Spring Boot dependency management. We will add Spring Boot dependencies to start our web application.

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

 

3. Web Controller

In order to log incoming request, we need to have a Spring Controller in place, we will be using a simple controller for our post. Read  Creating a Web Application with Spring Boot to get an understanding of creating a web application using Spring Boot.

@RestController
public class LoggingDemoController {

    @GetMapping("/demo/greeting")
    public String sayHello(){
        return "Hello Stranger !!!";
    }
}

There is nothing special with this controller and it is simply returning "Hello Stranger !!! " to the client.

 

4. Custom Solutions

We will not get into details for this solution, but we can Spring provides interceptors to perform actions before and after web request.You can use HandlerInterceptor to create your custom implementation to log incoming request.

You have to be careful while using such approach as input stream will be marked as consumed the moment it is read for the first time.

We can also use Spring’s ContentCachingRequestWrapper to handle above issue by storing request stream in the cache but this needs a certain amount of work and customization.

 

5. Spring Built-In Request Logging

Spring comes with ready to use a feature which can log your request, all we are required to configure this ready to use solution. Spring comes with AbstractRequestLoggingFilter, that perform logging operations before and after a request is processed.

Before we get into implementation details, this filter requires a subclass to override the beforeRequest(HttpServletRequest, String) and afterRequest(HttpServletRequest, String) methods to perform the actual logging around the request.

Spring provides following 2 implementations for AbstractRequestLoggingFilter

  1. CommonsRequestLoggingFilter
  2. ServletContextRequestLoggingFilter

 

ServletContextRequestLoggingFilter Simple request logging filter that writes the request URI (and optionally the query string) to the ServletContext log.We are going to discuss CommonsRequestLoggingFilter in this post.

 

5.1 CommonsRequestLoggingFilter using Spring Boot

Spring Boot is the new way to create and run your Spring-powered applications, we can enable CommonsRequestLoggingFilter by simply registering it as a bean with our application.

@Bean
public CommonsRequestLoggingFilter requestLoggingFilter() {
    CommonsRequestLoggingFilter loggingFilter = new CommonsRequestLoggingFilter();
    loggingFilter.setIncludeClientInfo(true);
    loggingFilter.setIncludeQueryString(true);
    loggingFilter.setIncludePayload(true);
    loggingFilter.setIncludeHeaders(false);
    return loggingFilter;
}

In addition to above configuration, we need to make sure to set log level as DEBUG for CommonsRequestLoggingFilter either through application.properties or YAML

logging.level.org.springframework.web.filter.CommonsRequestLoggingFilter=DEBUG

Once these configurations are in place, you should be able to see a similar output in the console

2017-10-25 19:52:02.708 DEBUG 70034 --- [io-10070-exec-4] o.s.w.f.CommonsRequestLoggingFilter      : Before request [uri=/demo/greeting;client=0:0:0:0:0:0:0:1]
2017-10-25 19:52:02.791 DEBUG 70034 --- [io-10070-exec-4] o.s.w.f.CommonsRequestLoggingFilter      : After request [uri=/demo/greeting;client=0:0:0:0:0:0:0:1]

And voila, you have your requests are getting logged.

5.2 CommonsRequestLoggingFilter without Spring Boot

If you are not using Spring Boot, You can configure this by using traditional Filter.We have following options to configure this in our traditional web application

  1. Configure this Filter either through xml configuration or Java configuration with default values.
  2. Create a custom filter by extending CommonsRequestLoggingFilter to modify default behaviour.

 

5.2.1 CommonsRequestLoggingFilter using XML

If you want to use CommonsRequestLoggingFilter with no changes, you can simply configure it in your application configuration file as a filer

<filter>
    <filter-name>requestLoggingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CommonsRequestLoggingFilter</filter-class>
    <init-param>
        <param-name>includeClientInfo</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>includePayload</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>includeQueryString</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>
 
5.2.2 CommonsRequestLoggingFilter using Java Web Initializer

If you are not a fan of using XML configuration for your web application, Spring provides a way to configure it using WebApplicationInitializer.Please note that WebApplicationInitializer Interface to be implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically.

public class MyWebAppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
        XmlWebApplicationContext appContext = new XmlWebApplicationContext();
        appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");

        ServletRegistration.Dynamic dispatcher =
                container.addServlet("dispatcher", new DispatcherServlet(appContext));
        dispatcher.setLoadOnStartup(1);
        dispatcher.addMapping("/");

        container.addFilter("requestLoggingFilter", CommonsRequestLoggingFilter.class)
                .addMappingForServletNames(null, false, "dispatcher");
    }

}
5.2.3 Custom CommonsRequestLoggingFilter

If you want to customize behaviour of CommonsRequestLoggingFilter, you can always create your custom Filter by extending CommonsRequestLoggingFilter

public class CustomeRequestLoggingFilter extends CommonsRequestLoggingFilter {

    // custom code
}

You can use any of the above options to configure your custom Filter.

 

Summary

In this post, we explore as of how to Log Incoming Request in Spring.Spring comes with many hidden features which can always help us to avoid writing custom/duplicate code and CommonsRequestLoggingFilter is one of such hidden gem in Spring.

Building an Application with Spring Boot

Building an Application with Spring Boot

In this post, we will explore Building an Application with Spring Boot. We will cover different aspects of Spring Boot along with different options to build an application using Spring Boot.

 

1. Introduction

Spring Boot is an opinionated, convention over configuration.Spring Boot takes away most part of the project set up by taking an opinionated view of the Spring platform so that new and existing users can quickly get to the bits they need.Spring Boot makes it easy to create a Spring-powered enterprise application with minimum fuss. 

 

2. Spring Boot Features

Spring Boot provides the following feature out of the box

  1. It simplifies Spring dependencies by taking the opinionated view ( we will discuss it in more details).
  2. Spring Boot provides a preconfigured set of technologies/framework to reduces error-prone configuration so we as a developer focused on building our business logic rather than thinking of project setup.
  3. You really don’t need those big XML configurations for your project.
  4. Embed Tomcat, Jetty or Undertow directly.
  5. Provide opinionated Maven POM to simplify your configuration

 

3. Creating Spring Boot Project

One of the main challenges to starting up a new project is the initial setup for the project. We need to take a call about the different directory structure and also need to make sure we are following all the industry standards.If you are using Maven, you might already be using Maven startup artefact which helps us to do those initial setups more quickly.

Spring Initializr is another great tool to quickly start Spring Boot projects. Spring Initializr is a web application that generates Spring Boot projects. Keep in mind that it will only generate project structure and not any code for you based on your preference (Maven or Gradle). If you are starting your project, my recommendation is to start with Spring Initializr.

There are multiple ways to use Spring Boot Initializr to generate project structure for you.

  1. Using  Spring Initializr Web Interface.
  2. Use Spring Boot CLI tool.
  3. Use your IDE

 

3.1 Using Spring Initializer Web Interface

This is the simplest way to generate project structure for your application.Open Spring Initializr Web interface your browser and you will be presented with a wizard to start your configurations.

 Building an Application with Spring Boot

You are required to fill some information in the web interface to start with

  1. What kind of project you want to generate (Maven or Gradle)
  2. What is your preferred language (Apart from Java you will get an option for Kotlin and Groovy)
  3. Spring Boot Version
  4. Standard project group and artefact details.
  5. Dependencies.

Dependencies is an interesting feature in the web interface, based on your selected Dependencies, web interface will automatically add Spring Boot Starter dependencies in the generated pom.xml file.In case you want a more control on the generated project structure or not sure what all dependencies you want to add to your project, click on the “Switch to the full version”.

Spring Boot

 

With the full version, you have the option to select Java version, packaging mode (maybe .war for traditional deployment) along with an option to select dependencies for your project. Once you click on “Generate Project” button, Spring Initializr will generate project you will be given a zip to download. You can import the unzipped project as a simple Maven/ Gradle based project in your IDE.

I will not be covering details as to how you can import this in your IDE. Please refer to relevant IDE document for more details.

 

3.2 Using Spring Boot CLI

We can also use Spring Boot CLI to generate structure for your project, once you have installed CLI, open command prompt and type spring. If CLI is installed correctly, you should be seeing the very similar output on typing spring.


localhost:~ javadevjournal$ spring
usage: spring [--help] [--version]
       [<args>]

Available commands are:

  run [options]  [--] [args]
    Run a spring groovy script

We can use init as an additional parameter with spring to create a new project. Spring Boot CLI will internally be going to use start.spring.io to generate project structure for you.

localhost:~ javadevjournal$ spring init --dependencies=web springboot-demo-project
Using service at https://start.spring.io
Project extracted to '/Users/umesh/springboot-demo-project'

It created springboot-demo-project directory with a maven based project using spring-boot-starter-web. This will create a project with the same default setting as available on the start.spring.io web interface. We can pass different parameters to customize project generation.

Let’s say we want to generate our project based on Java 1.7, we can pass --java-version=1.8 as an additional parameter to Spring Boot CLI.

spring init --java-version=1.7 --dependencies=web springboot-demo-project

When you will run above command, it will automatically set java-version in the generated pom.xml file as 1.7.

<properties>
    <java.version>1.7</java.version>
</properties>

If you are not sure what are the capabilities of the Spring init service, run init command with --list flag.

 spring init --list

 

4. Peek Inside pom.xml

Let’s start looking into pom.xml file to understand Spring Boot configurations in more detail. I will be covering only Spring Boot related changes in pom.xml. Here is the pom.xml file from our sample project.

<?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>com.umeshawasthi</groupId>
  <artifactId>ems</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>ems</name>
  <description>Employee Management System outline Spring Boot Features</description>

  <parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>1.5.4.RELEASE</version>
     <relativePath/> <!-- lookup parent from repository -->
  </parent>
   <!-- project properties repository -->
  <dependencies>
     <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>
        <!-- Spring boot test depedency -->
  </dependencies>
</project>

One of the main features of Spring Boot is the “Starters”, they are an easy way to add required dependencies (jars) in your classpath. When using Spring Boot, we don’t have to add jar/dependencies in your classpath (In case a starter is not available, you might have to add these dependencies in the pom.xml or can create your own custom starter). We just need to add correct “Starters” in our pom.xml file and Spring Boot will make sure to add those dependencies automatically.

 

5. Application Entry Point

@SpringBootApplication
public class EmsApplication {

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

Our main class is using @SpringBootApplication annotation. @SpringBootApplication is equivalent to using @Configuration, @EnableAutoConfiguration and @ComponentScan with their default values.If you are starting your project, it’s recommended to use annotation. Using @SpringBootApplication in your main class is equivalent to following 3 annotations

  1. @Configuration as a source of bean definitions.
  2. @EnableAutoConfiguration It gives Spring Boot an idea as to how you want to configure your application.
  3. @ComponentScan to automatically pick up all Spring components, including @Configuration classes.

 

5.2 Main Method

Another interesting feature of our main class is the main method. This is a standard method that will follow standard Java workflow. Our main class will pass on control to Spring Boot SpringApplication class. SpringApplication Class run method will be used to the BootStrap application. We will be taking a more deep look into the SpringApplication later section.

 

6. Hello World Controller

package com.javadevjournal.demo.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class HelloWorldController {

   @RequestMapping("/")
   public String helloWorld(){
       return "Hello World!!";
   }
}

There is nothing special in our Controller. It’s a standard Spring-MVC controller with standard Spring MVC annotations.

 

6. Running Application

It’s time to run our first Spring Boot powered application. We have multiple ways to run our Spring Boot application.

  1. If you are using IDE, you can use IDE to run your application.
  2. We can use mvn spring-boot:run command from the root directory to start our first Spring Boot application.
 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.4.RELEASE)

2017-07-08 15:49:50.319  INFO 1238 --- [           main] com.javadevjournal.demo.EmsApplication   : Starting EmsApplication on localhost with

Open up the browser of your choice and type http://localhost:8080, you should see “Hello World” as an output.

 

Summary 

Spring Boot provides a good boost to the Spring-based applications. In this post, we learned about different options of Building an Application with Spring Boot.Setting up a new project is always a challenging task and we need to make sure to manage all dependencies but with Spring Boot, it was really easy and we able to run our first web application with only new lines of code without thinking much about the required dependencies or the deployment.

Custom Banners in Spring Boot

How to Use Custom Banners in Spring Boot

When we start our Spring Boot application, it comes up with a default Banner, in this post we will discuss how to use Custom Banners in Spring Boot application.

 

Introduction

It’s highly likely that you want to release your own product/application based on the Spring Boot and want to display your own custom banner in place of default Spring Boot Banner.By default Spring

By default, Spring Boot application will display the following banner on startup

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.7.RELEASE)<

 

1. Creating Custom Banner

In order to start, we need to create a custom banner which will be used to display on the application startup time. I will be using  Spring Boot Banner Generator to upload an image for generating ANSI character in the plain text.You can always generate it manually if you want :).

For this tutorial, I will be using  Spring Logo logo from Spring IO site. 

 

2. Using The Custom Banner

In the above section, we have created a custom banner and it’s time to start using this custom banner.We will be creating a file banner.txt under the src/main/resources folder and will paste content in this file.

Spring Boot by default will pick content from the banner.txt file, in case it will find a banner.txt in our project classpath (resources folder of our application), it will pick custom banner content and will display it on the startup.

In case we want Spring Boot to pick banner content from other location and not from the default banner.txt, we can customize that by setting banner.location to the location of such a file

banner.location=classpath:/path/to/banner/custom-banner.txt

Here is the output when we run our application with new content in banner.txt file

Custom Banners in Spring Boot
Custom Banners in Spring Boot

 

2.1 Using Image for Custom Banner

We can even use the image as a custom banner for our Spring Boot application, We can add banner.gif, banner.jpg or banner.png image file to your classpath and Spring Boot will automatically pick this image as a startup banner. Please note that we need to name these banner images as a banner.extension (e.g. banner.jpg). 

You can use banner.image.location property to set a custom location for our banner image in the application.properties file, we can also use some additional properties to customize our banner


banner.image.location=classpath:banner.gif # Banner image file location (jpg/png can also be used).
banner.image.width= # Width of the banner image in chars (default 76)
banner.image.height= # Height of the banner image in chars (default based on image height)
banner.image.margin= # Left hand image margin in chars (default 2)
banner.image.invert= # If images should be inverted for dark terminal themes (default false)

Images will be converted into an ASCII art representation before getting printed on the startup which can add a lot of time on startup in case we have a complex image.It is recommended to use text format for a Custom Banners in Spring Boot.

If you want you can use SpringApplication.setBanner(… ) method to set custom banner programmatically but in my opinion, this is not preferred way and you need to implement your own printBanner() provided under org.springframework.boot.Banner interface. 

 

Summary 

In this short post, we learned how to use a Custom Banners in Spring Boot. We explored the option to create a custom banner using a banner.txt file or placing your custom image in your classpath.