Showing posts with label Spring. Show all posts

In this post, we will externalize the properties used in the application in a property file and will use PropertyPlaceHolderConfigurer to resolve the placeholder at application startup time.

Java Configuration for PropertyPlaceHolderConfigurer

@Configuration
public class AppConfig {

  @Bean
  public PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
    propertySourcesPlaceholderConfigurer.setLocations(new ClassPathResource("application-db.properties"));
    //propertySourcesPlaceholderConfigurer.setIgnoreUnresolvablePlaceholders(true);
    //propertySourcesPlaceholderConfigurer.setIgnoreResourceNotFound(true);
    return propertySourcesPlaceholderConfigurer;
  }
}

We created object of PropertySourcesPlaceholderConfigurer and set the Locations to search. In this example we used ClassPathResource to resolve the properties file from classpath. You can use file based Resource which need absolute path of the file.

DBProperties file

@Configuration
public class DBProperties {
 
  @Value("${db.username}")
  private String userName;
 
  @Value("${db.password}")
  private String password;
 
  @Value("${db.url}")
  private String url;

  //getters for instance fields
}

We used @Value annotation to resolve the placeholders.

Testing the configuration

public class Main {
  private static final Logger logger = Logger.getLogger(Main.class.getName());
 
  public static void main(String[] args) {
    try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class, DBProperties.class);) {
      DBProperties dbProperties = context.getBean(DBProperties.class);
      logger.info("This is dbProperties: " + dbProperties.toString());
    }
  }
}

For testing, we created object of AnnotationConfigApplicationContext and got DBProperties bean from it and logged it using Logger. This is the simple way to externalize the configuration properties from framework congfiguration. You can also get the full example code from Github.

In this post, we will discuss about Digest Authentication with Spring Security. You can also read my previous post on Basic Authentication with Spring Security.

What is Digest Authentication?

  • This authentication method makes use of a hashing algorithms to encrypt the password (called password hash) entered by the user before sending it to the server. This, obviously, makes it much safer than the basic authentication method, in which the user’s password travels in plain text (or base64 encoded) that can be easily read by whoever intercepts it.
  • There are many such hashing algorithms in java also, which can prove really effective for password security such as MD5, SHA, BCrypt, SCrypt and PBKDF2WithHmacSHA1 algorithms.
  • Please remember that once this password hash is generated and stored in database, you can not convert it back to original password. Each time user login into application, you have to regenerate password hash again, and match with hash stored in database. So, if user forgot his/her password, you will have to send him a temporary password and ask him to change it with his new password. Well, it’s common trend now-a-days.

Let's start building simple Spring Boot application with Digest Authentication using Spring Security.

Adding dependencies in pom.xml

We will use spring-boot-starter-security as maven dependency for Spring Security.

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

Digest related Java Configuration

@Bean
DigestAuthenticationFilter digestFilter(DigestAuthenticationEntryPoint digestAuthenticationEntryPoint, UserCache digestUserCache, UserDetailsService userDetailsService) {
  DigestAuthenticationFilter filter = new DigestAuthenticationFilter();
  filter.setAuthenticationEntryPoint(digestAuthenticationEntryPoint);
  filter.setUserDetailsService(userDetailsService);
  filter.setUserCache(digestUserCache);
  return filter;
}
 
@Bean
UserCache digestUserCache() throws Exception {
  return new SpringCacheBasedUserCache(new ConcurrentMapCache("digestUserCache"));
}
 
@Bean
DigestAuthenticationEntryPoint digestAuthenticationEntry() {
  DigestAuthenticationEntryPoint digestAuthenticationEntry = new DigestAuthenticationEntryPoint();
  digestAuthenticationEntry.setRealmName("GAURAVBYTES.COM");
  digestAuthenticationEntry.setKey("GRM");
  digestAuthenticationEntry.setNonceValiditySeconds(60);
  return digestAuthenticationEntry;
}

You need to register DigestAuthenticationFilter in your spring context. DigestAuthenticationFilter requires DigestAuthenticationEntryPoint and UserDetailsService to authenticate user.

The purpose of the DigestAuthenticationEntryPoint is to send the valid nonce back to the user if authentication fails or to enforce the authentication.

The purpose of UserDetailsService is to provide UserDetails like password and list of role for that user. UserDetailsService is an interface. I have implemented it with DummyUserDetailsService which loads every passed userName's details. But, you can restrict it to some few user or make it Database backed. One thing to remember is the password passed need to be in plain text format here. You can also use InMemoryUserDetailsManager for storing handful of user configured either through Java configuration or with xml based configuration which could access your application.

In the example, I also have used the caching for UserDetails. I have used SpringBasedUserCache and underlying cache is ConcurrentMapCache. You can use any other caching solution.

Running the example

You can download the example code from Github. I will be using Postman to run the example. Here are the few steps you need to follow.

1. Open postman and enter url (localhost:8082).

2. Click on Authorization tab below the url and select Digest Auth from Type dropdown.

3. Enter username(gaurav), realm(GAURAVBYTES.COM), password(pwd), algorithm(MD5) and leave nonce as empty. Click Send button.

4. You will get 401 unauthorized as response like below.

5. If you see the Headers from the response, you will see "WWW-Authenticate" header. Copy the value of nonce field and enter in the nonce textfield.

6. Click on Send Button. Voila!!! You got the valid response.

This is how we implement Digest Authentication with Spring Security. I hope you find this post informative and helpful.

In this post we will discuss about Basic Authentication and how to use it using Spring Security.

BASIC Authentication

  • It’s simplest of all techniques and probably most used as well. You use login/password forms – it’s basic authentication only. You input your username and password and submit the form to server, and application identify you as a user – you are allowed to use the system – else you get error.
  • The main problem with this security implementation is that credentials are propagated in a plain way from the client to the server. Credentials are merely encoded with Base64 in transit, but not encrypted or hashed in any way. This way, any sniffer could read the sent packages over the network.
  • HTTPS is, therefore, typically preferred over or used in conjunction with Basic Authentication which makes the conversation with the web server entirely encrypted. The best part is that nobody can even guess from the outside that Basic Auth is taking place.

Let's create a simple Spring Boot application which Basic Authentication enabled. You can read my previous post on how to create Simple Spring Boot application, if not familiar with it.

Add dependencies in pom.xml

We will add spring-boot-starter-security dependency to the pom.xml

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

Configurations for Basic Authentication

We need to register BasicAuthenticationFilter and BasicAuthenticationEntryPoint as bean in the Spring context.

@Bean
BasicAuthenticationFilter basicAuthFilter(AuthenticationManager authenticationManager, BasicAuthenticationEntryPoint basicAuthEntryPoint) {
  return new BasicAuthenticationFilter(authenticationManager, basicAuthEntryPoint());
}
 
@Bean
BasicAuthenticationEntryPoint basicAuthEntryPoint() {
  BasicAuthenticationEntryPoint bauth = new BasicAuthenticationEntryPoint();
  bauth.setRealmName("GAURAVBYTES");
  return bauth;
}

Enabling basic authentication and configuring properties

Basic Authenication is by default enabled when you add spring-security in your classpath. You need to configure the username and password for basic authentication. Here are some of the security properties. You can see SecurityProperties for other properties that you can configure like realm name etc.

security: 
  basic: 
    enabled: true
  user: 
    name: gaurav
    password: bytes

XML based configuration for Basic Authentication

<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="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-3.2.xsd
          http://www.springframework.org/schema/security
          http://www.springframework.org/schema/security/spring-security-3.1.xsd">
 
    <http>
        <intercept-url pattern="/*" access="ROLE_USER" />
         
        <!-- Adds Support for basic authentication -->
        <http-basic/>
    </http>
 
    <authentication-manager>
        <authentication-provider>
            <user-service>
                <user name="gaurav" password="bytes" authorities="ROLE_USER" />
            </user-service>
        </authentication-provider>
    </authentication-manager>
</beans:beans>

This is how to enable basic authentication in Spring Boot application using Spring Security. You can get the full working example code for basic authentication on Github.

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.

In this post, we will create a spring context and will register bean via Java configuration file. You can see my previous post on how to create a simple spring core project.

What is @Configuration annotation?

@Configuration annotation indicates that there is one or more bean methods and spring containers can process to generate bean definitions at runtime. Also, @Bean annotation is used at method level to signifies that this will be registered as bean in spring context. Let's create a quick configuration class.

@Configuration
public class WelcomeGbConfig {

  @Bean
  GreetingService greetingService() {
    return new GreetingService();
  }
}

Now, we will create spring context as follows.

// using try with resources so that this context closes automatically
try (ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
      WelcomeGbConfig.class);) {
  GreetingService greetingService = context.getBean(GreetingService.class);
  greetingService.greet();
}

1) we created the spring context.
2) We got the bean from context.
3. We call greet() on bean object.

This is how you can use configuration file (Java based) to define bean and being processed by spring context. You can also find the full example code on Github.

In this post, we will create a Spring context and will get a bean object from it.

What is Spring context?

Spring context is also termed as Spring IoC container which is responsible for instantiate, configure and assemble the beans by reading configuration meta data from XML, Java annotations and/ or Java code in configuration files.

Technologies used

Spring 4.3.6.RELEASE, Maven Compiler 3.6.0 and Java 1.8

We will first create a simple maven project. You can select the maven-archtype-quickstart as archtype.

Adding dependencies in pom.xml

We will add spring-framework-bom in the dependency management.

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-framework-bom</artifactId>
      <version>4.3.6.RELEASE</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

The benefit of adding this are to manage the version of the added spring dependencies from one place. By this, you can omit mentioning version number for spring dependencies.

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <scope>runtime</scope>
</dependency>

Now, we will create a class GreetingService which is eligible to get registered as bean in Spring context.

@Service
public class GreetingService {
  private static final Logger logger = Logger.getLogger(GreetingService.class.getName());

  public GreetingService() {

  }

  public void greet() {
    logger.info("Gaurav Bytes welcomes you for your first tutorial on Spring!!!");
  }
}

@Service annotation at class-level means that this is service and is eligible to be registered as bean in Spring context.

Instantiating a container

Now, we will create object of Spring context. We are using AnnotationConfigApplicationContext as spring container. Also, there exists other spring container like ClassPathXmlApplicationContext, GenericGroovyApplicationContext etc. which we will discuss in future posts.

ConfigurableApplicationContext context = new AnnotationConfigApplicationContext(
      "com.gauravbytes.hellogb.service");

As you see at the time of object contruction of AnnotationConfigApplicationContext, I am passing one string parameter. This parameter ( of varags type) is the basePackages which spring context will scan for bean registration.

Now, we will get object of bean by calling getBean() on spring context.

GreetingService greetingService = context.getBean(GreetingService.class);
greetingService.greet();

At last, we are closing the spring container by calling close().

context.close();
It is important to close the spring context(container) after use. By closing it, we ensure that it will release all the resources and locks that its implementation might hold and will also destroy all the cached singleton beans.

We have also included maven-compiler-plugin in pom.xml to compile the java sources with the configured java version (in our case it is Java 1.8).

You can also find the example code on Github.

Spring 4.3 - @GetMapping, @PostMapping, @PutMapping and @DeleteMapping

There are some new improvements in Spring Boot 1.4 and Spring 4.3 which lead to a better readability and some use of annotations, particularly with HTTP request methods.

We usually map GET, PUT, POST and DELETE HTTP method in rest controller in the following way.

@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

  @RequestMapping
  public ResponseEntity<List<Employee>> getAll() {
    return ResponseEntity.ok(Collections.emptyList());
  }

  @RequestMapping("/{employeeId}")
  public ResponseEntity<Employee> findById(@PathVariable Long employeeId) {
    return ResponseEntity.ok(EmployeeStub.findById(employeeId));
  }

  @RequestMapping(method = RequestMethod.POST)
  public ResponseEntity<Employee> addEmployee(@RequestBody Employee employee) {
    return ResponseEntity.ok(EmployeeStub.addEmployee(employee));
  }

  @RequestMapping(method = RequestMethod.PUT)
  public ResponseEntity<Employee> updateEmployee(@RequestBody Employee employee) {
    return ResponseEntity.ok(EmployeeStub.updateEmployee(employee));
  }

  @RequestMapping(path = "/{employeeId}", method = RequestMethod.DELETE)
  public ResponseEntity<Employee> deleteEmployee(@PathVariable Long employeeId) {
    return ResponseEntity.ok(EmployeeStub.deleteEmployee(employeeId));
  }
}

But with Spring Framework 4.3 and Spring Boot 1.4, we have new annotations to map the HTTP methods.

  • GET -> @GetMapping
  • PUT -> @PutMapping
  • POST -> @PostMapping
  • DELETE -> @DeleteMapping
  • PATCH -> @PatchMapping
/**
 * 
 * @author Gaurav Rai Mazra
 *
 */
@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

  @GetMapping
  public ResponseEntity<List<Employee>> getAll() {
    return ResponseEntity.ok(Collections.emptyList());
  }

  @GetMapping("/{employeeId}")
  public ResponseEntity<Employee> findById(@PathVariable Long employeeId) {
    return ResponseEntity.ok(EmployeeStub.findById(employeeId));
  }

  @PostMapping
  public ResponseEntity<Employee> addEmployee(@RequestBody Employee employee) {
    return ResponseEntity.ok(EmployeeStub.addEmployee(employee));
  }

  @PutMapping
  public ResponseEntity<Employee> updateEmployee(@RequestBody Employee employee) {
    return ResponseEntity.ok(EmployeeStub.updateEmployee(employee));
  }

  @DeleteMapping(path = "/{employeeId}")
  public ResponseEntity<Employee> deleteEmployee(@PathVariable Long employeeId) {
    return ResponseEntity.ok(EmployeeStub.deleteEmployee(employeeId));
  }
}

These annotations has improved the readability of the code. I hope you find this post helpful. You can get full example code on Github.