gauravbytes.com is now codefoundry.dev.

In the previous posts, we have created a Spring Boot QuickStart, customized the embedded server and properties and running specific code after spring boot application starts.

Now in this post, we will create Restful webservices with Jersey deployed on Undertow as a Spring Boot Application.

Adding dependencies in pom.xml

We will add spring-boot-starter-parent as parent of our maven based project. The added benefit of this is version management for spring dependencies.

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.0.RELEASE</version>
</parent>

Adding spring-boot-starter-jersey dependency

This will add/ configure the jersey related dependencies.

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

Adding spring-boot-starter-undertow dependency

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

These are all the necessary spring-boot-starters we require to create Restful webservices with Jersey.

Creating a Root resource/ Controller class

What are Root resource classes?

Root resource classes are POJOs that are either annotated with @Path or have at least one method annotated with @Path or a request method designator, such as @GET, @PUT, @POST, or @DELETE.

@Component
@Path("/books")
public class BookController {
  private BookService bookService;

  public BookController(BookService bookService) {
    this.bookService = bookService;
  }

  @GET
  @Produces("application/json")
  public Collection getAllBooks() {
    return bookService.getAllBooks();
  }

  @GET
  @Produces("application/json")
  @Path("/{oid}")
  public Book getBook(@PathParam("oid") String oid) {
    return bookService.getBook(oid);
  }

  @POST
  @Produces("application/json")
  @Consumes("application/json")
  public Response addBook(Book book) {
    bookService.addBook(book);
    return Response.created(URI.create("/" + book.getOid())).build();
  }

  @PUT
  @Consumes("application/json")
  @Path("/{oid}")
  public Response updateBook(@PathParam("oid") String oid, Book book) {
    bookService.updateBook(oid, book);
    return Response.noContent().build();
  }

  @DELETE
  @Path("/{oid}")
  public Response deleteBook(@PathParam("oid") String oid) {
    bookService.deleteBook(oid);
    return Response.ok().build();
  }
}

We have created a BookController class and used JAX-RS annotations.

  • @Path is used to identify the URI path (relative) that a resource class or class method will serve requests for.
  • @PathParam is used to bind the value of a URI template parameter or a path segment containing the template parameter to a resource method parameter, resource class field, or resource class bean property. The value is URL decoded unless this is disabled using the @Encoded annotation.
  • @GET indicates that annotated method handles HTTP GET requests.
  • @POST indicates that annotated method handles HTTP POST requests.
  • @PUT indicates that annotated method handles HTTP PUT requests.
  • @DELETE indicates that annotated method handles HTTP DELETE requests.
  • @Produces defines a media-type that the resource method can produce.
  • @Consumes defines a media-type that the resource method can accept.

You might have noticed that we have annotated BookController with @Component which is Spring's annotation and register it as bean. We have done so to benefit Spring's DI for injecting BookService service class.

Creating a JerseyConfiguration class

@Configuration
@ApplicationPath("rest")
public class JerseyConfiguration extends ResourceConfig {
  public JerseyConfiguration() {
  
  }
 
  @PostConstruct
  public void setUp() {
    register(BookController.class);
    register(GenericExceptionMapper.class);
  }
}

We created a JerseyConfiguration class which extends the ResourceConfig from package org.glassfish.jersey.server which configures the web application. In the setUp(), we registered BookController and GenericExceptionMapper.

@ApplicationPath identifies the application path that serves as the base URI for all the resources.

Registering exception mappers

Could there be a case that some exceptions occurs in the resource methods (Runtime/ Checked). You can write your own custom exception mappers to map Java exceptions to javax.ws.rs.core.Response.

@Provider
public class GenericExceptionMapper implements ExceptionMapper {

  @Override
  public Response toResponse(Throwable exception) {
    return Response.serverError().entity(exception.getMessage()).build();
  }
}

We have created a generic exception handler by catching Throwable. Ideally, you should write finer-grained exception mapper.

What is @Provider annotation?

It marks an implementation of an extension interface that should be discoverable by JAX-RS runtime during a provider scanning phase.

We have also created service BookService, model Book also. You can grab the full code from Githib.

Running the application

You can use maven to directly run it with mvn spring-boot:run command or can create a jar and run it.

Testing the rest endpoints

I have used PostMan extension available in chrome brower to test rest services. You can use any package/ API/ software to test it.

This is how we create Restful web-services with Jersey in conjuction with Spring Boot. I hope you find this post informative and helpful to create your first but not last Restful web-service.

Spring Boot provides two interfaces CommandLineRunner and ApplicationRunner to run specific piece of code when application is fully started. These interfaces get called just before run() on SpringApplication completes.

CommandLineRunner

This interface provides access to application arguments as string array. Let's see the example code for more clarity.

@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
  private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);

  @Override
  public void run(String... args) throws Exception {
    logger.info("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args));
  }
}

ApplicationRunner

ApplicationRunner wraps the raw application arguments and exposes interface ApplicationArguments which have many convinent methods to get arguments like getOptionNames() return all the arguments names, getOptionValues() return the agrument value and raw source arguments with method getSourceArgs(). Let's see an example code this.

@Component
public class AppStartupRunner implements ApplicationRunner {
  private static final Logger logger = LoggerFactory.getLogger(AppStartupRunner.class);

  @Override
  public void run(ApplicationArguments args) throws Exception {
    logger.info("Your application started with option names : {}", args.getOptionNames());
  }
}

When to use it

When you want to execute some piece of code exactly before the application startup completes, you can use it. In one of our project, we used these to source data from other microservice via service discovery which was registered in consul.

Ordering

You can register as many application/commandline runner as you want. You just need to register them as Bean in the application context and Spring Application will automatically picks them up. You can order them as well either by extending interface org.springframework.core.Ordered or by @Order annotation.

This is all about application/commandline runner. You can also see org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner in spring-batch which implements CommandLineRunner to register and start batch jobs at application startup. I hope you find this informative and helpful. You can grab the full example code on Github.

In the previous post, we have created a web-based Spring Boot application which uses Embedded Tomcat as the default server running on default port 8080. Spring Boot supports Tomcat, Undetow and Jetty as embedded servers. Now, we will change and/ or configure the default embedded server and common properties to all the available servers.

Spring Boot provides convenient way of configuring dependencies with its starters. For changing the embedded server, we will user its spring-boot-starter-undertow.

Adding dependencies

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

spring-boot-starter-web comes with Embedded Tomcat. We need to exclude this dependency.

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

This is all we need to do to change the embedded server. There are some generic properties which is applicable for every server and some server specific properties that we can tweak to improve the preformance. Let's change some of the server properties.

Changing the default server port

server.port property is used for configuring the port on our Spring Boot application should run.

Enabling compression on responses

You can enable to compression on response sent by server and can tweak the mimeTypes, minResponseSize for compression. By default, the compression is disabled. Default property value for mimeTypes is text/html, text/xml,text/plain,text/css,text/javascript,application/javascript. Default property value for minResponseSize is 2048 bytes.

Other server properties

You can also enable ssl, modify maxHttpPostSize, contextParameters, contextPath and other server related properties. To know more, see org.springframework.boot.autoconfigure.web.ServerProperties class.

Configuring sever-specific properties

You can also change embedded server specific properties. In our example, we have changed embedded server to Undertow and have tweaked its ioThreads and workerThreads properties.

A sample properties file which have above mentioned properties changes.

server:
  port: 8082
  undertow: 
    ioThreads: 15
    workerThreads: 150
    accesslog: 
      enabled: true
  compression: 
    enabled: true
    mimeTypes: text/xml, text/css, text/html, application/json
    minResponseSize: 4096

spring:
  application: 
    name: gaurav-bytes-embedded-server-example

I hope this post is informative and helpful. You can grab the full example code on Github.

In this post, we will create a simple Spring Boot application which will run on embedded Apache Tomcat.

What is Spring Boot?

Spring Boot helps in creating stand-alone, production-grade application easily with minimum fuss. It is the opinionated view of Spring framework and other third party libraries which believes in convenient configuration based setup.

Let's start building Spring Boot Application.

Adding dependencies in pom.xml

We will first add spring-boot-starter-parent as parent of our maven based project.

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>1.5.1.RELEASE</version>
</parent>

The benefit of adding spring-boot-starter-parent is that version managing of dependency is easy. You can omit the required version on the dependency. It will pick the one configured the parent pom or from starters pom. Also, it conveniently setup the build related configurations as well.

Adding spring-boot-starter-web dependency

This will configure/ add all the required dependencies for spring-web module.

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

Writing App class

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

@SpringBootApplication indicates that class is configuration class and also trigger the auto-configure through @EnableAutoConfiguration and component scanning through @ComponentScan annotation in it.

@EnableAutoConfiguration

It enables the auto-configuration of Spring Application Context. It attempts to configuration your application as per the classpath dependencies that you have added.

In the main() of App class, we have delegated the call to run() method of SpringApplication. SpringApplication will bootstrap and auto-configure our application and in our case will start the embedded tomcat server. In run method, we have passed App.class as argument which tells Spring that this is our primary spring component (helps in bootstrapping).

Writing HelloGbController

@RestController
public class HelloGbController {
  @GetMapping
  public String helloGb() {
    return "Gaurav Bytes says, \"Hello There!!!\"";
  }
}

I have used two annotations @RestController and @GetMapping. You can read more on new annotation introduced by Spring here.

@RestController signifies that this class is web @Controller and spring will consider it to handle incoming web requests.

Running the application

You can use maven command mvn spring-boot:run to run it as Spring Boot application and when you hit the localhost:8080 on your web browser, you will see the below web page.

Creating a jar for spring boot application

You need to add spring-boot-maven-plugin plugin to your build configuration in pom.xml and then you can create a jar with maven command mvn repackage and simply run it as jar with command java -jar spring-boot-quickstart-0.0.1-SNAPSHOT.jar.

<plugin>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-maven-plugin</artifactId>
</plugin>

This is how you can build a simple spring boot application. I hope you find this post helpful. You can download the example code from Github.

In this post, we will discuss about various bean scopes and their differences.

Bean scopes

There are seven bean scopes Spring supports out of which five are only available if your ApplicationContext is web-aware.

# Scope Explanation
1 singleton There will be single object of the bean per Spring IoC Container (Default).
2 prototype Scope beans to any number of object instances. Every time you get object of prototype bean from context, it will be brand new.
3 request Scope of the bean definition mapped to the lifecycle of HTTP Request. This is only available web-aware ApplicationContext.
4 session Scope of the bean definition mapped to the lifecycle of HTTP session. This is only available to web-aware ApplicationContext.
5 globalSession Scope of the bean definition mapped to the lifecycle of HTTP session usually used within Portlet context. This is only available to web-aware ApplicationContext.
6 application Scope of the bean definition mapped to the ServletContext. This is only available to web-aware ApplicationContext.
7 websocket Scope of the bean mapped to the lifecycle of Websocket. This is only available to web-aware ApplicationContext.

Singleton Vs Prototype

Let's see a example which shows the difference between Singleton and Prototype scope for bean.

public class Dictionary {
  private List words;
  public Dictionary() {
    words = new ArrayList<>();
  }
 
  public void addWord(String word) {
    this.words.add(word);
  }
 
  public int totalWords() {
    return this.words.size();
  }
 
  @Override
  public String toString() {
    return words.toString();
  }
}

We first defined a class Dictionary.

Singleton scope

There will be only one shared instance of singleton bean per context and all request for that bean definition will end up returning the same object by the container.

@Configuration
public class ScopeConfig {
  @Bean(name = "singletonDictionary")
  @Scope("singleton") 
  //you can omit the scope by default it is singleton
  Dictionary singletonDictionary() {
    return new Dictionary();
  }
}

We created a configuration class ScopeConfig. We created a bean Dictionary. @Scope annotation is used to mark the scope of the bean to singleton. If we don't define any scope then by default it is considered singleton scoped bean.

public class App {
  private static final Logger logger = Logger.getLogger(App.class.getName());
  public static void main(String[] args) {
    try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);) {
      Dictionary singletonDictionary = context.getBean("singletonDictionary", Dictionary.class);
      logger.info("Singleton Scope example starts");
      singletonDictionary.addWord("Give");
      singletonDictionary.addWord("Take");
      int totalWords = singletonDictionary.totalWords();
      logger.info("Need to have two words. Total words are : " + totalWords);
      logger.info(singletonDictionary.toString());
      singletonDictionary = context.getBean("singletonDictionary", Dictionary.class);
      logger.info("Need to have two words. Total words are : " + totalWords);
      logger.info(singletonDictionary.toString());
      logger.info("Singleton Scope example ends");
    }
  }
}

When we run above snippet, it will generate output like below.

Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: Singleton Scope example starts
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: Need to have two words. Total words are : 2
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: [Give, Take]
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: Need to have two words. Total words are : 2
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: [Give, Take]
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: Singleton Scope example ends

From output, we can analyse that when we got object of singletonDictionary again from context, it contained the previous added values.

Prototype scope

Prototype scope of bean results in the creation of a new bean instance every time a request for that specific bean is made.

@Configuration
public class ScopeConfig {
  @Bean(name = "prototypeDictionary")
  @Scope("prototype") 
  Dictionary prototypeDictionary() {
    return new Dictionary();
  }
}

We created a configuration class ScopeConfig. We defined a bean prototypeDictionary. We used @Scope annotation to mark its scope as prototype.

public class App {
  private static final Logger logger = Logger.getLogger(App.class.getName());
  public static void main(String[] args) {
    try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(ScopeConfig.class);) {
      Dictionary prototypeDictionary = context.getBean("prototypeDictionary", Dictionary.class);
      logger.info("Prototype scope example starts");
      prototypeDictionary.addWord("Give 2");
      prototypeDictionary.addWord("Take 2");
      logger.info("Need to have two words. Total words are: " + prototypeDictionary.totalWords());
      logger.info(prototypeDictionary.toString());
      prototypeDictionary = context.getBean("prototypeDictionary", Dictionary.class);
      logger.info("zero word count. Total words are: " + prototypeDictionary.totalWords());
      logger.info(prototypeDictionary.toString());
    }
  }
}

The above code snippet generated below output.

Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: Prototype scope example starts
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: Need to have two words. Total words are: 2
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: [Give 2, Take 2]
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: zero word count. Total words are: 0
Feb 12, 2017 11:50:18 PM com.gauravbytes.springbeanscope.App main
INFO: []

From the output logs, you can clearly see that when we got prototypeDictionary object again from context then it returned a new object and there was no previously added words in it.

When to use Singleton and Prototype

Use prototype scope for all stateful beans and singleton scope for stateless beans.

This is all about bean scopes. I hope you find this post informative. You can find the example code on Github.

What is Dependency Injection?

Dependency injection is a process in which objects define their dependencies i.e. other objects they require to work, through a constructor, setter methods, factory methods. The container responsibility is to inject those while creating beans. With Dependency inject in place, we have cleaner code and clear way of decoupling. There are two prominent variants of Dependency Injection.

  • Constructor based Dependency Injection
  • Setter based Dependency Injection

Constructor based Dependency Injection

When you express your dependencies through constructor arguments and your container invoke your constructor with number of arguments, type of arguments expected by the constructor. Let's jump to one quick example.

@Component
public class ConstructorBasedFileParser {
  private Parser parser;

  @Autowired
  public ConstructorBasedFileParser(Parser parser) {
    this.parser = parser;
  }

  public void setParser(Parser parser) {
    this.parser = parser;
  }

  public void parseFile(File file) {
    if (parser.canParse(file)) {
      parser.parse(file);
    }
  }
}

In the above code snippet, ConstructorBasedFileParser is a component which express its dependency on Parser through constructor using @Autowired annotation.

Configuration class for the above code snippet looks like this.

@Configuration
@Import(value = ParserConfig.class)
@ComponentScan(basePackages = "com.gauravbytes.di.parser.constructor")
public class ConstructorBasedDIConfig {

}

@Configuration declares it as Spring Configuration file. @ComponentScan is used along with Configuration classes to scan for components. @Import imports the one or more Configuration classes. It is equivalent to <import/>.

Setter based Dependency Injection

Setter based dependency injection is accomplished by calling setter methods on beans after invoking no-args constructor by the container. Let's jump to example to see how to use setter method dependency injection.

@Component
public class SetterBasedFileParser {
  private Parser parser;

  public SetterBasedFileParser() {
  }

  @Autowired
  public void setParser(Parser parser) {
    this.parser = parser;
  }

  public void parseFile(File file) {
    if (parser.canParse(file)) {
      parser.parse(file);
    }
  }
}

In above code snippet, SetterBasedFileParser is a component class which expresses its dependency through setter method setParser() using @Autowired annotation.

When to use Constructor-based vs Setter-based DI?

Per se Spring documentation, use constructor-based DI for mandatory dependencies and setter-based DI for optional dependencies. It is advisable to use constructor-based DI. It makes your classes as Immutable object and also ensured that required dependencies are met before constructing that bean. Also, if you want to reconfigure your bean, then use setter-based DI.

Circular dependencies

There could be a case when your open bean say A is dependent on B and B is dependent on bean A (Both expressing dependencies through constructor). Spring IoC container will detect this at runtime and will throw BeanCurrentlyInCreationException.

Possible solution is to use setter based injection in some of beans.

I hope you find this post useful. You can grab the full example code used on Github.

In this post, we will learn about @Import annotation and its usage. You can see my previous post on how to create a simple spring core project.

What is @Import annotation and usage?

@Import annotation is equivalent to <import/> element in Spring XML configuration. It helps in splitting the single Java based configuration file into small, modular, maintainable and component based configuration. Let's see it with example.

@Configuration
@Import(value = { DBConfig.class, WelcomeGbConfig.class })
public class HelloGbAppConfig {

}

In above code snippet, we are importing two different configuration files viz. DBConfig, WelcomeGbConfig in application level configuration file HelloGbAppConfig.

The above code is equivalent to Spring XML based configuration below.

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

  <import resource="config/welcomegbconfig.xml"/>
  <import resource="config/dbconfig.xml"/>

</beans>

You can see the full example code for Java based configuration on Github.