Category: Spring Framework

Spring Framework: Profiling with @Profile

 

In your software development life, you might be having an experience about different application environments such as DEVELOPMENT, STAGING and PRODUCTION. The developed applications are normally deployed in these environments.  The most of the time these environments are set up in separate servers and they are known as :

  • Development Server
  • Staging Server
  • Production Server

Each of these server environments has their own configuration and connection details. These details might be different from one server to another.

e.g:-
MySQL or some other database connection details
RabbitMQ server and connection details etc....

 

Therefore we should maintain separate configuration/properties files for each server environment and we need to pick up the right configuration file based on the server environment.

In traditional way, this is achieved by manually defining related configuration file when building and deploying the application. This requires few manual steps with some human resource involvement. Therefore there is a probability to arise deployment related issues.  In addition, there are some limitations with the traditional approach.

 

What we should do if there is a requirement to programmatically register a bean based on the environment?

e.g:- The staging environment should have a separate bean implementation while development and production environments are having their own bean instances with different implementations.

The Spring Framework has come up with the solutions for above problems and made our life easier with annotation called @Profile.

 

@Profile

In spring the above deployment environments (development, staging and production) are treated as separate profiles@Profile annotation is used to separate the configuration for each profile. When running the application, we need to activate a selected profile and based on activated profile the relevant configurations will be loaded.

The purpose of @Profile is to separate/segregate the creating and registering of beans based on the profiles. Therefore @Profile can be used with any annotation that has the purpose of either creating or registering bean in Spring IOC container. So the @Profile can be used with following annotations.

  • Any stereo type annotations (mainly used with @Component and @Service)
  • @Configuration and @Bean annotations

 

After reading the above note, the first question you might be asking yourself is that “Why @Profile is used mainly with @Component and @Service? “. Lets figure it out before moving forward.

 

 

Why @Profile annotation is used mainly with @Component and @Service annotations? 

@Component designates the class as a spring managed component and @Service designates the class as the spring managed service. It makes a sense if the application creates different services and managed components based on the activated profiles. This is very logical and this should be the expected behavior of profiling.

Do you think that creating separate controllers and repositories based on different profiles make any sense? Is it logically acceptable? Different Controller for production environment and different ones for staging and development? Isn’t it crazy?

On the other hand, do you think that we need separate repositories based on profiles. Separate ones for development, staging and production?  wait… wait.. wait…  I agree with you that we need different database configurations and connection details for each of these environments.  Does it mean that we need separate repositories? No right? The separate database connection details does not have any relation with repository.

Now i think you can understand why @Profile is not used with @Controller and @Repository.

 

 

What will happen if it is used with other stereotype annotations such as  @Controller and @Repository?

It will work fine. I just just explained you the logical reasons behind of not using @Profile with @Controller and @Repository.

If you can logically prove that using @Profile with @Controller and @Repository annotations just do the right job for you, then you are free to go for it. But again think twice before proceeding.

Ok. Now you have an idea of how @Profile helps to create and register the relevant beans based on activated profiles. But i didn’t explain you how relevant application.properties file is picked up based on the activated profile. Lets look at it now.

 

Picking up the correct application.properties file with spring boot

According to our discussion, the application can be deployed in several server environments. Therefore the application should have different application.properties file for the deployment profile(or server environment).  When the profile is activated, the corresponding application.properties file should be picked up.

How the properties files are named based on the profile and Spring Boot picks up the correct application.properties file?

We can have property file specific to a profile with the convention application-{profile}.properties. In this way we can have separate property file for different environment. If we have activated a profile, then the corresponding property file will be used by the spring boot application. We can also have a property file for default profile.

Suppose we have profiles as dev for development environment , prod for production environment and staging for staging environment. Then the property file will be listed as below.

application-prod.properties
application-dev.properties 
application-staging.properties

 

Ok lets do some fantastic coding example with Spring @Profile. We will try to cover most of the concepts we discussed here.

 

What we are going to build.

We will build a simple REST api application that persists some data to MySQL database with Spring Data JPA.  Here i am focused only with demonstrating @Profile and if you need to learn more about Spring Data JPA, please refer my article on that.

Click here to go to Spring Data JPA article. 

This application has three different databases that represents three different deployment profiles. deployment profiles are dev, staging and prod.

app_development_db  - database for the dev profile/environment 
app_staging_db - database for the staging profile/environment
app_production_db  - database for the prod  profile/environment.

(If you want to run this application and see the output, make sure that you have created above three databases in the MySQL server)

The source code of this example can be found at GitHub.

Click here to download the source code. 

 

If you open up the project in your IDE, you can see the following files structure.

Screen Shot 2018-01-03 at 12.58.22 AM.png

 

You can notice that we have created separate application.properties files for each profile.

So lets dig into some of the important source files.


@Configuration
public class ConfigurationManager
{
@Bean
@Profile("dev")
public AppConfiguration getDevelopmentConfiguration()
{
return new AppConfiguration("development_config");
}
@Bean
@Profile("staging")
public AppConfiguration getStagingConfiguration()
{
return new AppConfiguration("staging_config");
}
@Bean
@Profile("prod")
public AppConfiguration getProductionConfiguration()
{
return new AppConfiguration("production_config");
}
}

 

ConfigurationManager is responsible for creating and registering the relevant/corresponding  bean based on the activated profile.

 

EnvironmentService has different implementations for each profile. Based on the activated profile, the corresponding service bean will be created and registered.


import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
@Service
@Profile("dev")
public class DevelopmentEnvironmentService implements EnvironmentService
{
@Override
public String getCurrentEnvironment()
{
return "development_environment";
}
}


@Service
@Profile("prod")
public class ProductionEnvironmentService implements EnvironmentService
{
@Override
public String getCurrentEnvironment()
{
return "production_environment";
}
}


@Service
@Profile("staging")
public class StagingEnvironmentService implements EnvironmentService
{
@Override
public String getCurrentEnvironment()
{
return "staging_environment";
}
}

 

Finally we will look at our ApplicationLogController.


@RestController
public class ApplicationLogController
{
@Autowired
private AppConfiguration appConfiguration;
@Autowired
private EnvironmentService environmentService;
@Autowired
private ApplicationLogRepository repository;
@PostMapping("/logs")
public ApplicationLog createApplicationLog()
{
ApplicationLog applicationLog = new ApplicationLog();
applicationLog.setConfiguration(appConfiguration.getName());
applicationLog.setEnvironment(environmentService.getCurrentEnvironment());
return repository.save(applicationLog);
}
}

 

ApplicationLogController has exposed following REST endpoint.

POST  /logs

This will persists the ApplicationLog entries with the aid of ApplicationLogRepository. After that it reruns the persisted log entry. This can be seen in the body of the HTTP Response.

 

AppConfiguration has been auto-wired with the registered configuration bean based on the activated profile.

 EnvironmentService will also be auto-wired with the created service bean based on the activated profile.

Ultimately, the persisting database will be decided on the selected properties file based activated profile.

Since everything depends on the activated profile,  we need to run this application by activating any of these three profiles. Then we can see the result and understand how it works.

 

Running the Application by activating profiles.

The profile can be activated with following command.

-Dspring.profiles.active=<<profile-name>>

 

Therefore the practical uses of the command can be given as follows.

 

Running spring boot application by enabling “prod” profile

mvn spring-boot:run -Dspring.profiles.active=prod

Running the application as a jar file by enabling the dev profile

java -jar -Dspring.profiles.active=dev target/spring-profile-example-0.0.1-SNAPSHOT.jar

 

Lets run the application and examine how the profile works. In order to identify how it works, please check all three databases after each REST api call.

 

Run the application by activating  “prod” profile

java -jar -Dspring.profiles.active=prod target/spring-profile-example-0.0.1-SNAPSHOT.jar

Making the REST api call.

/POST  localhost:8080/logs

 

The HTTP response will be as follows.

Screen Shot 2018-01-03 at 10.31.01 PM.png

 

 

Run the application by activating  “dev” profile

java -jar -Dspring.profiles.active=dev target/spring-profile-example-0.0.1-SNAPSHOT.jar

Making the REST api call.

/POST  localhost:8080/logs

 

The HTTP response will be as follows.

Screen Shot 2018-01-03 at 10.34.12 PM.png

 

 

Run the application by activating  “staging” profile

java -jar -Dspring.profiles.active=staging target/spring-profile-example-0.0.1-SNAPSHOT.jar

Making the REST api call.

/POST  localhost:8080/logs

 

The HTTP response will be as follows.

Screen Shot 2018-01-03 at 10.35.51 PM.png

 

As i have already mentioned, please check all three database after each REST api call. Then you will notice that only the corresponding application.properties file is picked up and the connection for the given database is made.

 

Spring Framework : Asynchronous task execution with @Async

Reason for Asynchronous Task Execution

In this article, i am expected discuss about the Spring’s Asynchronous task execution capability with @Async annotation. In software development, we have found some situations/scenarios where we need to execute some code segments/piece of logics asynchronously.  The following situations can be given as the examples.

  • sending email or sms for a user.
  • complex logic/data processing

Assume that you are trying to register  for http://www.facebook.com and you are filling the registration form. once the registration form is summited, facebook should send you a confirmation email to activate your account. It will take considerable amount of time to send the confirmation email to the user. This is because, the facebook application may need to connect with the email server to send the email. Assume that it takes around 15 seconds to send the email. Then what will be your user experience.

Synchronous way:  You need to stay on the registration page until the application send you the confirmation email. Once the email is sent, the application will return a success response back to the application.  No choice. You have to hang on the registration page for at least 15 seconds (as we have agreed)  to get the success notification on the registration.  In the technical point of view, the caller Thread will get blocked (will have to wait) until all the logics are get executed.

Asynchronous way:  The task of sending email is delegated to a separate thread and it will be executed in the background (in a separate thread). Then the application does not wait until the email is sent and immediately send the success response back to the caller (ma be for the front end application).  In technical point of view, the caller does not have to wait until the all the logics get executed. Those will be executed in background threads.

The optimal and correct way to  execute these tasks as asynchronous background tasks.

Spring support for Asynchronous task execution

In spring it is possible to execute asynchronous tasks with @Async annotation. The logic inside the method that is annotated with @Async will be executed in a new separate thread. It does not execute in the caller’s thread.

 

Spring configuration for Asynchronous

@EnableAsync

This is a class level annotation and should be applied for any of the configuration class. This will enable the spring asynchronous task execution support for your application. Normally, this can be applied in the main configuration class of the application. The following code segment demonstrates the use of @EnableAsync with spring boot project.

@SpringBootApplication
@EnableAsync
public class SpringBootApplication{

(configuration class means a class that is annotated with @Cofiguration )

 

Is it required to use @EnableAsync ?

If you do not have applied this annotation for any of your configuration classes, the methods with @Async annotation will executed in the same thread. (caller thread)

 

@Async

This is a method level annotation. The code inside the annotated method will be executed in a new background thread (apart from the main thread).

Simply, if you need to execute a piece of code in a new background thread (Other than the calling thread), then put them inside a method that is annotated with @Async.

Few Rules with @Async

In order to apply the @Async for a method, it should meet the following requirements.

  • method should have the public access level.
  • method should have the void return type or the actual return type must be wrapped with Future interface (java.util.concurrent.Future).

The following are valid method declarations.

public void sendEmail(){}

public Future generateReport(){}

 

Ok.. Now it is enough with theories. Lets look at some coding examples.  The full source code of the application can be found at GitHub.

Click here to download the source code.

 

Project Strucure

I have assumed that you have cloned the source code and open it in your preferable IDE. Now you will see the project structure as follows.

Screen Shot 2017-11-14 at 1.17.12 AM.png

You will see that we have three workers.

  1. AsyncWorker – for demonstrating spring asynchronous method execution.
  2. NonAsyncWorker – for demonstrating the consequences of not using Spring asynchronous method execution. (executing the tasks in synchronous manner)
  3. AsyncWorkerFuture – for demonstrating how the result of asynchronous method execution is retrieved with Future interface.

 

Building and Running the Project


package com.springbootdev.samples.springbootasynctask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class SpringBootAsyncTaskApplication implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(SpringBootAsyncTaskApplication.class);
@Autowired
private WorkerService workerService;
public static void main(String[] args) {
SpringApplication.run(SpringBootAsyncTaskApplication.class, args);
}
@Override
public void run(String… strings) throws Exception
{
if (strings == null || strings.length == 0) {
LOGGER.error(" worker type is expected as the command line parameter ");
return;
}
if (strings[0].equals("non-async")) {
workerService.runNonAsyncWorkers();
}
else if (strings[0].equals("async")) {
workerService.runAsyncWorkers();
}
else if (strings[0].equals("future")) {
workerService.runAsyncWorkersWithFutureReturnType();
}
}
}

 

By looking at the spring boot configuration file, you can see that this application is developed to be run as a command line application. In order to invoke the relevant worker, you need to provide the matching command line argument.

 

command for building the application. 

mvn clean install

 

Executing the NonAsyncWorker

For executing the NonAsyncWorker, it is required to run the application with “non-async” as the command line argument.

java -jar target/spring-async-task-app.jar  non-async

 

when this command is run, the runNonAsyncWorkers() method of the WorkerService will get executed.


public void runNonAsyncWorkers()
{
long startTime = System.currentTimeMillis();
LOGGER.info(" start of executing all non async workers ");
for (int round = 0; round < 5; round++) {
nonAsyncWorker.execute();
}
LOGGER.info("Non Async workers: total execution time [" + ((System.currentTimeMillis() – startTime))/1000 + "] seconds");
}

runNonAsyncWorkers() will repeatedly invoke the execute() method of the NonAsyncWorker five times.  once all the invocation are over, it will log the total execution time before completing the method execution.

 

Here is the code of the NonAsyncWorker.


package com.springbootdev.samples.springbootasynctask.worker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class NonAsyncWorker
{
private static final Logger LOGGER = LoggerFactory.getLogger(NonAsyncWorker.class);
public void execute()
{
LOGGER.info("NonAsyncWorker : current thread [" + Thread.currentThread().getName() + "]");
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
LOGGER.info(" sleeping thread interrupted ");
}
}
}

NonAsyncWorker has a one method called execute(). it will print the current thread name and wait for 3 seconds before completing the method.

Here is the console output after executing the NonAsyncWorker.

Screen Shot 2017-11-14 at 2.05.18 AM.png

 

Now it is obvious that the WorkerService is started by the main thread and all the invocations of the NonAsyncWorker are also handled by the same thread (that is main thread). All of them will be executed in a sequential manner. Each invocation is guaranteed to be executed for at least 3 seconds.  Therefore it should take at least 15 seconds to complete all interactions.  If you properly examine the time log in console output, you will notice that our calculations has been proven.

 

Executing the AsyncWorker

In this way, each invocation will be handled in a separate thread apart from the calling(main) thread.

For executing the AsyncWorker, it is required to run the application with “async” as the command line argument.

java -jar target/spring-async-task-app.jar async

 

when this command is run, the runAsyncWorkers() method of the WorkerService will get executed.


public void runAsyncWorkers()
{
long startTime = System.currentTimeMillis();
LOGGER.info(" start of executing all async workers ");
for (int round = 0; round < 5; round++) {
asyncWorker.execute();
}
LOGGER.info(" Async workers: total execution time [" + ((System.currentTimeMillis() – startTime))/1000 + "] seconds ");
}

 

runAsyncWorkers() will repeatedly invoke the execute() method of the AsyncWorker five times.  once all the invocation are over, it will log the total execution time before completing the method execution.

 

Here is the code of the AsyncWorker.


package com.springbootdev.samples.springbootasynctask.worker;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.stereotype.Component;
@EnableAsync
@Component
public class AsyncWorker
{
private static final Logger LOGGER = LoggerFactory.getLogger(AsyncWorker.class);
@Async
public void execute()
{
LOGGER.info(" AsyncWorker: current thread [" + Thread.currentThread().getName() + "]");
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
LOGGER.info(" sleeping thread interrupted ");
}
LOGGER.info(" AsyncWorker: completed [" + Thread.currentThread().getName() + "]");
}
}

 

AsyncWorker has a one method called execute(). it will print the current thread name and wait for 3 seconds before completing the method. Once the sleeping time is completed, it will log the name of the thread as completed.

Here is the console output after executing the NonAsyncWorker.

Screen Shot 2017-11-26 at 7.32.23 PM.png

You can see that all the invocations has been happened in the same time (even if it is not shown here, there should be milliseconds of delay between each invocation and that can be neglected). In addition, you can notice that each invocation is handled by a separate thread apart from the main thread.  once the main thread has completed all iterations for method invocations, it will continue the main thread. you can see that all the interactions has been completed with less than 1 second. that is why it is logged as 0 seconds.(as i mentioned earlier, definitely there will be a milliseconds of duration)

each invocation has been waited/slept for 3 seconds and logged as completed with their handling thread name. If you look at the starting time and completing time of each thread, that is somewhere around 3 seconds. since all invocations has happened concurrently, it has taken only 3 seconds to complete all 5 invocations.

 

Executing Async work with Return (AsyncWorkerFuture)

In this way, each invocation will be handled in a separate thread apart from the calling(main) thread and main thread will wait to retrieve the result of the async task .

For executing the AsyncWorkerFuture, it is required to run the application with “async” as the command line argument.

java -jar target/spring-async-task-app.jar future

 

when this command is run, the  runAsyncWorkersWithFutureReturnType() method of the WorkerService will get executed.


public void runAsyncWorkersWithFutureReturnType() throws Exception
{
LOGGER.info(" start of returning async worker");
Future<String> future = asyncWorkerReturn.execute();
String result = (String) this.getResultOfFuture(future);
LOGGER.info(" returned result is [" + result + "] ");
}
private Object getResultOfFuture(Future future) throws Exception
{
if (future.isDone()) {
return future.get();
}
LOGGER.info(" waiting for result ");
Thread.sleep(1000);
return getResultOfFuture(future);
}


public void runAsyncWorkersWithFutureReturnType() throws Exception
{
LOGGER.info(" start of returning async worker");
Future<String> future = asyncWorkerReturn.execute();
String result = (String) this.getResultOfFuture(future);
LOGGER.info(" returned result is [" + result + "] ");
}
private Object getResultOfFuture(Future future) throws Exception
{
if (future.isDone()) {
return future.get();
}
LOGGER.info(" waiting for result ");
Thread.sleep(1000);
return getResultOfFuture(future);
}

isDone() method of the Future can be used to check whether future is completed with the returned output. if it is completed, the get() method can be used to retrieve the result.

Here is the console output of the execution.

Screen Shot 2017-11-26 at 8.09.50 PM.png

 

Hope you have got a good understanding of  how to handle asynchronous method execution in spring.

Spring Framework: New Annotation for RequestMapping (@GetMapping, @PostMapping, @DeleteMapping, @PutMapping)

 

Spring Framework 4.3 has introduced few convenient annotations for HTTP Request Mapping based on the HTTP Request Method.

 

Old Way New Way
@RequestMapping(value = “/test”, method = RequestMethod.GET) @GetMapping(“/api/customers”)
@RequestMapping(value = “/test”, method = RequestMethod.POST) @PostMapping(“/api/create”)
@RequestMapping(value = “/test”, method = RequestMethod.PUT) @PutMapping(“/api/update”)
@RequestMapping(value = “/test”, method = RequestMethod.DELETE) @DeleteMapping(“/api/delete”)
@RequestMapping(value = “/test”, method = RequestMethod.PATCH) @PatchMapping(“/api/update”)

 

Here is the Sample code

@RestController
public class RestApiController
{
   @GetMapping(value = "/user")
   public String getMappingExample()
   {
      return "HTTP GET : Request Mapping";
   }

   @PostMapping(value = "/user")
   public String postMappingExample()
   {
      return "HTTP POST : Request Mapping";
   }

   @PutMapping(value = "/user")
   public String putMappingExample()
   {
      return "HTTP PUT : Request Mapping";
   }

   @DeleteMapping(value = "/user")
   public String deleteMappingExample()
   {
      return "HTTP DELETE : Request Mapping";
   }
}

Spring Framework: @PathVariable and @RequestParam

 

@PathVariable and @RequestParam are Spring MVC based annotations used for two different purposes. One is for accessing the path variable in the request URI and other one is for accessing the query param in query string.

 

@PathVariable

As name implies, @PathVariable annotation is used to access the variable value in the URI path.

POST   http://www.springbootdev.com/api/users/1/profile

@PostMapping("/api/users/{user_id}/profile")
public String getPathVariable(@PathVariable("user_id") Integer userId)
{
      //TODO implementation should goes here
}

 

Here you can see that user_id path variable is represented by userId variable. According to the sample URI request, the value of userId variable will be 1.

 

@RequestParam

@RequestParam annotation is used to access the query param in the query string. Then you might be wondering about “what is query string“.

 

What is query string?

Wikipedia says “On the World Wide Web, a query string is the part of a uniform resource locator (URL) containing data that does not fit conveniently into a hierarchical path structure. The query string commonly includes fields added to a base URL

http://www.springbootdev.com/departments/1/students?subject=IT&country=LK

In here,  subject=IT&country=LK can be identified as query string.

 

Here is the sample code for accessing above query string (subject and country)

@PostMapping("/departments/{department_id}/students")
public List<Student> getStudents(@RequestParam("subject") String subject,
                                 @RequestParam("country") String country) {
     //TODO implementation should goes here
}

 

Can we access both @RequestParam and @PathVariable in the same method?

 

Absolutely YES.  Please refer the sample code.

http://www.springbootdev.com/departments/1/students?subject=IT&country=LK

 

@PostMapping("/departments/{department_id}/students")
public List<Student> getStudents(
  @PathVariable("department_id") Integer departmentId,
  @RequestParam("subject") String subject,
  @RequestParam("country") String country) {

      //TODO implementation should goes here
}

 

Here you can see that path variable is represented by the departmentId and query params are represented  by subject and country variables.

 

JAX-RS  : @QueryParam and @PathParam

@PathVariable and @RequestParam  are Spring framework owned annotations. Therefore those annotations can be used only within the spring based web applications.

What will happen if you are building a RESTful web service without using Spring? Lets assume that we build JAX-RS web service. how do you access path variable and query parameters?  JAX-RS has the equivalent annotations for above spring based annotations and they do the same job.

@PathVariable (Spring based)  --- equivalent ---  @PathParam (JAX-RS)

@RequestParam (Spring based)  --- equivalent ---  @QueryParam (JAX-RS)

Spring Framework: @Component vs @Bean Annotations

most of the developers has confused about the real use and the purpose of @Bean and @Component annotations. most of them are thinking that they are just two annotations used for same purpose. This is completely wrong idea and those are two different annotations used for two different purposes. lets look at each of their purpose.

 

@Component

This is a generic annotation and can be applied to any class of the application to make it a spring managed component(simply, generic stereotype for any spring managed component). when the classpath is scanned by the spring’s component-scan (@ComponentScan) feature, it will identify the classes annotated with @Component annotation (within the given package) and create the beans of such classes and register them in the ApplicationContext. @Component is a class level annotation and its purpose it to make the class as spring managed component and auto detectable bean for classpath scanning feature.

if you want to know more about  @Component and other stereo type annotations, it is recommended to look at this article.

 

@Bean

@Bean is used to explicitly declare and register a bean (as a configuration bean) in Spring IOC container that is returned from a method. @Bean is a method level annotation and it is used within a class that is annotated with @Configuration. Simply, @Bean annotation is used to register the bean returned by a method as a spring configuration bean in IOC Container.  @Bean is only a method level annotation and it cannot be used with classes and object declaration.

@Bean annotation indicates that a method produces a bean that should be managed by the Spring container.

   To declare a bean, simply annotate a method with the @Bean annotation. When JavaConfig encounters such a method, it will execute that method and register the return value as a bean within a ApplicationContext. By default, the bean name will be the same as the method name.The following is a simple example of a @Bean method declaration.

 

@Configuration
public class ApplicationConfig {

 @Bean
 public User adminUserProfile() 
 {
     return new User("Chathuranga","Tennakoon");
 }
}
In the ApplicationConfig class, you can see that we first use the @Configuration annotation to inform Spring that this is a Java-based configuration file. Afterward, the @Bean annotation is used to declare a Spring bean and the DI requirements.
The @Bean annotation is equivalent to the <bean> tag, the method name is equivalent to the id attribute within the <bean> tag.

I hope that after reading this article, you have  got a clear idea about the real purpose and use of @Bean and @Component annotations.

 

 

Spring Framework: @Component, @Service, @Repository and @Controller

In order to continue with this article, you should have a proper understanding of Spring component scanning feature.  if you don’t know about it, please go through Component Scanning in Spring article before continue with this one.

 

@Component, @Repository, @Service and @Controller annotations

Spring @Component, @Service, @Repository and @Controller annotations are used for automatic bean detection/discovery using classpath scanning (@ComponentScan) in Spring framework. Those annotation will indicate the component scanner that those beans are spring managed beans. These annotations are called Stereotype annotations as well.

@Component is a generic annotation/stereotype and can be applied to any class within the project to make it as spring managed component. Then it will be automatically detected during the Spring classpath scanning. Difference of @Service, @Repository, @Controller with @Component is that they are special cases of @Component and used for particular purposes.

E.g:- spring managed components in the persistence, service, and presentation layers.

For all these annotations (stereotypes), technically the core purpose is same. Spring automatically identifies all these classes that are annotated with  @Component, @Service, @Repository, @Controller  during classpath scanning and registers bean in ApplicationContext.

Spring IOC DI (1)

Continue reading “Spring Framework: @Component, @Service, @Repository and @Controller”

Spring Framework: Spring Component scanning with @ComponentScan

Any class that is annotated with @Component or its special purpose annotation (@Controller, @Service or @Repository) can be identified as a spring managed bean or component. The spring framework should have the capability of identifying those annotated spring managed beans and creates and register them in spring ApplicationContext.  The component scanning will do this for spring.

The spring framework has a feature called component scanning and it will scan for the @Component or its special purposes annotations(as mentioned above) within the specified class packages(class-paths) for identifying spring managed components. After that it will create and register those components in the Spring ApplicationContext for the use of other components in the application.

 

How the component scanning is configured?

There are two ways.

  • Annotation based Configuration
    @ComponentScan(basePackages = {“com.springbootdev.samples”})
  • XML based Configuration
    <context:component-scan base-package =“com.springbootdev.samples”/>

(use either XML based or Annotation based configuration on your preference)

In simply, these configurations tells the spring to scan the given package (in this case “com.springbootdev.samples”) and its sub packages for finding the bean classes (spring managed components) that are annotated with @Component, @Controller, @Repostory and @Service. Once the relevant classes are discovered, Spring will create the instances of such annotated bean classes and register themselves in the ApplicationContext when the Spring IOC container loads.

 

During the initialization of Spring’s ApplicationContext, Spring will discover those @Autowired, @Inject and @Resource annotations and inject the dependencies as required. 

 

The @ComponentScan tag tells Spring to scan the code for injectable beans annotated with @Component, @Controller, @Repository, and @Service as well as supporting the @Autowired, @Resource and @Inject annotations under the package (and all its sub-packages) specified.

Spring MVC : What is @RequestBody and @ResponseBody ?

 

@RequestBody and @ResponseBody annotations are used to convert the body of the HTTP request and response with java class objects. Both these annotations will use registered HTTP message converters in the process of converting/mapping HTTP request/response body with java objects.

The source code for this article can be found in the GitHub.

Click here to download the source code.

What is the HTTP Message Converter and Why it is used?

The client (web browser or REST client) cannot send the java objects (as it is) in the body of the HTTP request. On the other hand, the server application cannot compose the body of the HTTP response with java objects (as it is). Simply the HTTP Request and Response body cannot contains the in the form of java objects.

HTTP request and response body should contain either JSON , XML or some other type of formatted data (RSS etc).  Therefore the HTTP message converters are used to convert the HTTP request body (either in JSON or XML) to the Java objects and Java objects back to XML or JSON for embedding into the HTTP response body.

 

How the Message Converter Works?

you might be having a little confusion of how message converters are exactly worked. How the spring frameworks picks the right message converter that can transform the HTTP request body into the targeted java class object. On the other hand, how the server application responds back with exactly the similar type (either XML or JSON) that is expected by the client.  This is achieved by checking the headers of the HTTP request. Lets look at what are those headers in detailed.

 

Content-Type 

This header informs the server application about the content type of the body of the HTTP Request. Based on the content type, the server application picks the correct message converter out of the available message converters  for converting the HTTP Request body into the java class object.

e.g:-

  • If the Content-Type is application/json , then it will select a JSON to Java Object converter.
  • If the Content-Type is application/xml , then it will select a XML to Java Object converter.

 

Accept

This header informs the server application about the Acceptable media type of the body of the HTTP Response (Simply what the client will accept from the server). Based on the value of the Accept header, the server application picks the correct message converter out of the available message converters  for converting returned java class object(s) to the requested media type.

e.g:-

  • If the Accept is application/json , then it will select a Java Object to JSON converter.
  • If the Accept is application/xml ,  then it will select a Java Object to XML converter.

 

@RequestBody

This is used to convert the body of the HTTP request to the java class object with the aid of selected HTTP message converter. This annotation will be used in the method parameter and the body of the http request will be mapped to that method parameter. As described above, the message converter is selected based on the value of Content-Type  Header of the HTTP request.

 

@ResponseBody

This annotation is used to add the return value to the body of the HTTP response with the aid of selected HTTP message converter. As described above, the message converter is selected based on the value of Accept Header of the HTTP request. @RestController is the preferred way to achieve the same functionality earlier provided by @ResponseBody. Under the hood, @RestController is @Controller + @ResponseBody, and it avoids the need of prefixing every method with @ResponseBody.

 

Ok. enough theories. Lets do some cool stuffs with coding.  You can download the following samples from GitHub.

 

The following dependency has been added to configure/register the  HTTP message converter for XML type.

 <dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-xml</artifactId>
 </dependency>

 

The source code of UserController has posted below and you can see that the single method available there. It can accept request body with both JSON and XML content types. In addition, it can produces both JSON and XML content types in response body.

 


import com.springbootdev.examples.domain.entity.User;
import com.springbootdev.examples.domain.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static org.springframework.http.MediaType.*;
@RestController
@RequestMapping("/api")
public class UserController
{
@Autowired
private UserRepository userRepository;
@PostMapping(
value = "/users",
consumes = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE},
produces = {APPLICATION_JSON_VALUE, APPLICATION_XML_VALUE}
)
public User create(@RequestBody User user)
{
return userRepository.save(user);
}
}

 

@RequestBody will help to convert the body of the HTTP Request to the User object.  The method can handle a request body that is in the form of either XML or JSON.  The transformed user object will be saved to database using the userRepository. The persisted user object will be retuned by the method.

Since the class is annotated with @RestController, every method in the class is implicitly annotated with @ResponseBody.  Therefore the returned value/object will substitute the body of the HTTP Response. The body of the HTTP Response can be either XML or JSON.

Before building and running the application, make sure that you have changed the datasource configurations of  the application.properties to your development environment.

 


## Spring DATA SOURCE Configurations
spring.datasource.url = jdbc:mysql://localhost:3306/spring_examples_db?useSSL=false
spring.datasource.username = root
spring.datasource.password = test123
## Hibernate Properties
# The SQL dialect makes Hibernate generate better SQL for the chosen database
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
# Hibernate ddl auto (create, create-drop, validate, update)
spring.jpa.hibernate.ddl-auto = update

 

Ok lets run the application and make few api calls with Postman.

 

Round 1

POST   /api/users

Content-Type : application/json
Accept : application/json

Screen Shot 2018-01-01 at 11.31.51 PM.png

 

Request Body and Response Body

Screen Shot 2018-01-01 at 11.31.14 PM.png

 

Round 2

POST   /api/users

Content-Type : application/json
Accept : application/xml

 

Request Body and Response Body

Screen Shot 2018-01-01 at 11.35.57 PM.png

 

Round 3

POST   /api/users

Content-Type : application/xml
Accept : application/xml

 

Request Body and Response Body

Screen Shot 2018-01-01 at 11.37.49 PM.png

 

Round 4

POST   /api/users

Content-Type : application/xml
Accept : application/json

 

Request Body and Response Body

Screen Shot 2018-01-01 at 11.39.46 PM.png

 

 

ResponseEntity

I just wanted to explain you  about the ResponseEntity even if it is not mentioned in the code example.

ResponseEntity is a real deal. It represents the entire HTTP response. Good thing about it is that you can control anything that goes into it. You can specify status code, headers, and body. It comes with several constructors to carry the information you want to sent in HTTP Response.

 

Spring Framework: @Autowired , @Inject and @Resource

What the purpose of @Autowired in spring? Where it can be applied?

@Autowired annotation tells the spring to auto-wire/inject the relevant bean(s) and its collaborators/dependencies with Spring IOC container. (with the support of Spring Dependency Injection)

There are three places where you can use @Autowired to auto-wire a bean. Those are on the setter method, constructor or a field.

The @Autowired annotation tells Spring where an injection needs to occur. If you put it on a method “setMovieFinder” it understands (by the prefix set + the @Autowired annotation) that a bean needs to be injected. In the second scan, Spring searches for a bean of type “MovieFinder”, and if it finds such bean, it injects it to this method. If it finds two such beans you will get an Exception. To avoid the Exception, the @Qualifier annotation can be used.

 

Continue reading “Spring Framework: @Autowired , @Inject and @Resource”