Spring Boot
Spring Boot
Spring Boot is a combination of two words “Spring” and “Boot”. Spring Boot is
an open-source java-based framework that helps in bootstrapping the Spring
Application.
“Spring Boot makes it easy to create stand-alone, production-grade Spring
based Applications that you can just run”.
Why is Spring Boot so popular?
1. Spring Boot speeds up the project development.
2. It provides an easier and faster way to configure, set up & run both web-
based as well as simple applications.
3. No web servers like (Tomcat, Jetty, Undertow) are required to configure
separately. Therefore, no need to deploy any war file manually.
4. Reduces XML configurations and promotes annotations.
5. Combines more than one annotation of Spring framework & replaces them
by introducing a single annotation.
For example, @SpringBootApplication is a combination of three annotations -:
@EnableAutoConfiguration, @Configuration, @ComponentScan
9. Automatically configures Spring.
11. Provides easy integration mechanism with many third party tools.
13. Spring Boot Application easily integrates with its ecosystem like Spring
JDBC, Spring ORM, Spring Data, Spring Security, Spring Web MVC etc.
14. It integrates with databases very easily because its internally integrate a
spring data JPA.
There are plenty of ways of defining active profiles in Spring Boot, including
command line arguments, Maven settings, JVM system parameters,
environment variables, spring.profiles.active property,
and SpringApplication methods.
How many ways are there to create a Spring Boot Application?
In order to create a Spring Boot Application, we have multiple ways.
spring-boot-starter- Starter for using Tomcat as the embedded servlet container. Default
tomcat servlet container starter used by starter-web
spring-boot-starter-
data-jpa for using Spring Data JPA with Hibernate
spring-boot-starter-
data-jdbc Starter for using Spring Data JDBC
spring-boot-starter- for building web, including RESTful, applications using Spring MVC.
web Uses Tomcat as the default embedded container
@Bean
We use @Bean at method level. If you remember the xml configuration of a
Spring, it is a direct analog of the XML <bean/> element. It creates Spring
beans and generally used with @Configuration. A class with @Configuration
(we can call it as a Configuration class) will have methods to instantiate objects
and configure dependencies. Such methods will have @Bean annotation. By
default, the bean name will be the same as the method name. It instantiates
and returns the actual bean. The annotated method produces a bean
managed by the Spring IoC container.
@Configuration
public class AppConfig {
@Bean
public Employee employee() {
return new Employee();
}
@Bean
public Address address() {
return new Address();
}
}
<beans>
<bean name="employee" class="com.dev.Employee"/>
<bean name="address" class="com.dev.Address"/>
</beans>
The annotation supports most of the attributes offered by <bean/>, such
as: init-method, destroy-method, autowiring, lazy-init, dependency-check, depen
ds-on and scope.
@Component
This is a main stereotype annotation as a class level and interface level. which
indicates that the class is a Spring-managed bean/component. It registers
them into the Application Context as a Spring Bean. When we use this
annotation with class, that class then automatically bean will be created
while using component scan-based annotation configuration. @Controller,
@Service and @Repository are move specific alternatives to @Component.
@Component
class MyBean { }
@Component("myTestBean")
class MyBean { }
@Controller
@Controller annotation comes under the Stereotype category of annotations
that works as specialization of @Component annotation. We use this
annotation with the class, in case of this annotation we need to use
@ResponseBody explicitly. We can used inside the class @RequestMapping
and http request like as @GetMapping, @PostMapping ….
@Controller is a specialized @Component marked as a controller
@RestController-: combination of @Controller +@ResponseBody
@RestController tells Spring Framework that the class annotated with
@RestController will work as a controller in a Spring REST project. It is
combination of @Controller and @ResponseBody get features of REST API.
@Service
@Service tells Spring Framework that the class and interface annotated
with @Service is a part of service layer and it will include business logics of the
application. This annotation behaves similarly to @Component. The only
difference it helps our classes more readable, using this annotation with class
indicates this is our service class (mostly our business logic exists in these
classes).
@Repository
@Repository tells Spring Framework that the class annotated with
@Repository is a part of data access layer and it accessing data from the
database in the application. This annotation used with DAO interfaces.
@Bean vs @Component
@Component is a class level annotation whereas @Bean is a method level
annotation and name of the method serves as the bean name. @Bean
annotation has to be used within the class and that class should be annotated
with @Configuration. However, @Component needs not to be used with
the @Configuration. @Component auto detects and configures the beans using
classpath scanning, whereas @Bean explicitly declares a single bean, rather
than letting Spring do it automatically.
@Configuration
@Import({ DataSourceConfig.class, MyCustomConfig.class })
public class AppConfig extends ConfigurationSupport {
// @Bean methods here that can reference @Bean methods in DataSourceConfig or
MyCustomConfig
}
@Configuration
public class DataSourceConfig {...}
@Component
public class MyCustomConfig {...}
@Value
We can use this annotation to inject values into fields of Spring managed
beans. We can apply it at field or constructor or method parameter level.
let’s first define a property file, then inject values of properties using @Value.
server.port=9898
server.ip= 10.10.10.9
emp.department= HR
columnNames=EmpName,EmpSal,EmpId,EmpDept
Now inject the value of server.ip using @Value as below:
In controller used
@Value("${server.ip}")
private String serverIP;
@EnableAutoConfiguration
@EnableAutoConfiguration enables auto-configuration of beans present in the
classpath in Spring Boot applications. This annotation enables Spring Boot to
auto-configure the application context. Therefore, it automatically creates and
registers beans that are part of the included jar file in the classpath and also
the beans defined by us in the application.
// this annotation automatically configure the spring application based on the
jar dependency that we have added pom.xml file.
we don’t need to explicitly declare a package names using @ComponentScan.
@Configuration
@EnableAutoConfiguration(excludeName =
{"org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessag
ingAutoConfiguration"})
public class MyWebSocketApplication {
public static void main(String[] args) {
}
}
@SpringBootConfiguration
This annotation is a part of Spring Boot Framework. However,
@SpringBootApplication inherits from it. Therefore, if an application uses
@SpringBootApplication, it is already using @SpringBootConfiguration. Moreover,
it’s acts as an alternative to the @Configuration annotation. The primary
difference is that @SpringBootConfiguration allows configuration to be
automatically discovered. @SpringBootConfiguration indicates that the class
provides configuration and also applied at the class level. Particularly, this is
useful in case of unit or integration tests. For example, observe the below code
@SpringBootConfiguration
public class MyApplication { public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
@Bean
public IEmployeeService employeeService() {
return new EmployeeServiceImpl();
}
}
@Configuration
@EnableConfigurationProperties(MyDevAppProperties.class)
public class MySpringBootDevApp { }
Finally create a Test Runner to test the values of properties as
below.
@Component
public class DevPropertiesTest implements CommandLineRunner {
@Autowired
private MyDevAppProperties devProperties;
@Override
public void run(String... args) throws Exception {
System.out.println("App Name = " + devProperties.getName());
System.out.println("DB Url = " + devProperties.getDburl());
System.out.println("DB User = " + devProperties.getDbuser());
}
}
@Autowired
@Autowired facilitates to resolve and inject the object dependency implicitly. It
internally uses setter or constructor injection. It works with reference only. We
can use @Autowired on properties or fields, setters, and constructors.
@Service
public class PaymentService {
public void doPayment() { .... }
}
Then, we’ll inject this bean into the PaymentController bean using
@Autowired on the field definition as below:
@Controller
public class PaymentController {
@Autowired
private PaymentService service;
@Qualifier
The @Qualifier annotation provides additional information to @ Autowired
annotation while resolving bean dependency. If more than one bean of the
same type is available in the container, we need to tell container explicitly
which bean we want to inject, otherwise the framework will throw
an NoUniqueBeanDefinitionException, indicating that more than one bean is
available for autowiring.
public interface PaymentService { }
@Service
public class CardPaymentService implements PaymentService { }
@Service
public class CashPaymentService implements PaymentService { }
@Controller
public class PaymentController {
@Autowired
@Qualifier("cardPaymentService")
private PaymentService service;
@Autowired
@Qualifier("cashPaymentService")
private PaymentService service;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
@Controller
@Controller annotation comes under the Stereotype category of annotations
that works as specialization of @Component annotation. This annotation tells
the Spring IOC container to treat this class just as a Spring MVC controller. We
can used inside the class @RequestMapping and http request like as @GetM
apping, @PostMapping …..
@Controller
public class MyMvcController { }
@RequestMapping
We use this annotation to map client requests with the appropriate method to
serve the request. Apart from Spring MVC, Spring WebFlux also supports this
annotation. @RequestMapping annotation provides various options as its
attributes to offer its customized behaviour. Below is the list of attributes it
provides.
value -: represents the primary mapping which becomes a part of our URL.
Most of the times, for a simple request, we use only this attribute.
path -: Alias for value, supports Ant-style path patterns, relative paths at
method level. Path mapping URIs may contain placeholders e.g. “/${profile
path}”
method : represents the HTTP request method. However, now-a-days we
use @GetMapping, @PostMapping annotations as a replacement of this
attribute.
params : represents the parameters of the mapped request, yet another way of
narrowing the request mapping.
consumes : represents the consumable media types of the mapped request.
headers : represents the headers of the mapped request.
name : assigns a name to this mapping.
produces : represents the producible media types of the mapped request.
@Controller
public class HelloController {
@RequestMapping(
value = {"/hello"},
params = {"id","name"},
method = {RequestMethod.GET},
consumes = {"text/plain"},
produces = {"application/json","application/xml"},
headers = {"name=Robert", "id=1"}
)
public String helloWorld() {
return "Hello";
}
}
We can use this annotation at both class level and method level. we have more
handy modern annotations(available in Spring 4.3+) to use at method level
such as @GetMapping, @PostMapping etc.
@GetMapping, @PostMapping, @PutMapping, @PatchMapping,
@DeleteMapping
@GetMapping annotation is the HTTP method ‘GET’ specific variant of the
annotation @RequestMapping. It is a shortcut version of the ‘@RequestMapping‘
and applies on top of the method that expects HTTP ‘GET’ request. Let’s look
once at the API source code of annotation @GetMapping.
@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = { RequestMethod.GET })
public @interface GetMapping {
String name( ) default "";
String[ ] value() default {};
String[ ] path() default {};
String[ ] params() default {};
String[ ] headers() default {};
String[ ] consumes() default {};
String[ ] produces() default {};
}
@GetMapping vs @RequestMapping
As source code of @GetMapping shows that it is already annotated
with @RequestMapping(method = { RequestMethod.GET }). It indicates that we
don’t need to specify ‘method = { RequestMethod.GET }‘when
using @GetMapping. For example, below code demonstrates the concept:
@RequestMapping(value = "/emp/{empid}", method =
RequestMethod.GET)
is equivalent to ⇓
@GetMapping("/emp/{empid}")
Similarly, to handle different types of incoming HTTP requests, Spring supports
five types of HTTP method specific annotations. They are @GetMapping,
@PostMapping, @PutMapping, @PatchMapping, @DeleteMapping for HTTP
methods GET, POST, PUT, PATCH and DELETE respectively.
In Spring MVC, you will definitely have a form to fill the values and submit it
on click of a provided button. Instead of parsing each field value of your form
individually, you can populate all fields value at one go with the help of
@ModelAttribute annotation. This is commonly known as data binding in
Spring MVC. For example, the code below that follows the ‘Invoice‘ model
attribute is populated with data from a form submitted to the saveInvoice
endpoint. Spring MVC does this behind the scenes before invoking the submit
method:
@ModelAttribute at method argument level
@PostMapping("/saveInvoice")
public String saveInvoice(@ModelAttribute("invoice") Invoice invoice) {
// Code that uses the invoice object to save it
// service.saveInvoice(invoice);
return "invoiceListView";
}
@ModelAttribute at method level
Moreover, besides using @ModelAttribute at method argument, we can also
use it at method level. When used at the method level, it adds one or more
model attribute values in the Model that can be identified globally. It means,
methods annotated with @ModelAttribute apply to all methods that are
annotated with @RequestMapping or even @GetMapping and @PostMapping.
However, our method annotated with @ModelAttribute will be the very first to
run, before the rest of the @RequestMapping methods.
@ModelAttribute
public void includeAttributes(Model model) {
model.addAttribute("message", "additional attribute to all methods");
}
In the example above, includeAttributes() method will add an attribute named
‘message’ to all models defined in the controller class. Generally, Spring MVC
will always make first call to this method, prior to calling any other request
handler methods.
♥ Note: It is also important to note that you need to annotate the respective
controller class with @ControllerAdvice. Then only, you can add values in the
Model that will be identified globally(in all request handler methods).
@RequestParam
@RequestParam annotation binds the value of web request parameter with the
value of Controller’s method parameter. It acts just like getRequestParameter()
method of HttpServletRequest. We send data to application using URL in the
form of /user?uid=5&uname=Robin.
For example, below code demonstrates the concept:
@RestController
@RequestMapping("/user")
public class UserRestController {
@GetMapping("/getUser/{uid}")
public User getUser(@PathVariable String uid) {....}
}
The code above indicates that the class UserRestController will act as a
RestController for the application.
@PathVariable
We use @PathVariable to bind value of variable at URL path with request
handler’s method parameter. In @RequestParam, we were sending data via URL
with query string (?) and then ‘key=value’. In @PathVariable also, we can send
multiple data separated by ‘/’ but without using ‘?’ and key-value. In order to
read the dynamic value, variable in the URL path should be enclosed with curly
braces such as “URL/user/{id}“.
For example, below code demonstrates the use of @PathVariable:
@GetMapping("/user/{id}/{name}")
public String getUserDetails ( @PathVariable Integer id,
@PathVariable String name) {
return "Path variable data is: " + id + "-" + name;
}
In order to access getUserDetails(), your URL should be like
http://localhost:8080/user/10/Robin
In Spring, method parameters annotated with @PathVariable are required by
default. However, to make it optional, we can set the required property
of @PathVariable to false as below:
@PathVariable(required = false) String name
Moreover, Since Spring 4.1, we can also use java.util.Optional<T> (introduced in
Java 8) to handle a non-mandatory path variable as below:
@GetMapping("/user/{id}/{name}")
public String getUserByIdAndName(@PathVariable
Optional<String> id,
@PathVariable String name){
if (id.isPresent()) { return "ID: " + id.get();}
else {return "ID not present";}
}
@RequestParam vs @PathVariable
We generally use @RequestParam in form-based Spring MVC projects
whereas @PathVariables in Spring REST applications. Almost all Web
technologies in Java supports @RequestParam as it is a basic concept of
Servlet API. But it is not true with @PathVariable. One major difference is
that @PathVarible follows the order of variables whereas
in @RequestParam order of variables doesn’t matter.
URL pattern Validity
/user?id=10&name=Robin Valid
/user?name=Robin&id=10 Valid
/user/10/Robin Valid
/user/Robin/10 Invalid :
MethodArgumentTypeMismatchException(NumberFormatException)
with "status": 400, "error": "Bad Request"
From the table above, it is clear that we have to take extra care while accessing
a request handler method in terms of variable order in @PathVariable.
As opposed to @RequestParam, URL created for @PathVariable is called as Clean
URL and it also takes less characters to send data.
@ResponseBody
In Spring Boot, @ResponseBody, by default, converts return type data into
JSON format in case of non-string return type data(e.g. Employee,
Employee<String> etc.). Hence, if return type of request handler method is
String, @Responsebody will not do any conversion of returning data. We don’t
need to apply this annotation explicitly as Spring will internally apply it by
default when we annotate a class with @RestController.
@RequestBody
If we are sending input data in form of JSON/XML(Global data format) to a
Spring Boot REST producer application via request handler method, then it will
convert Global data into Object format(based on the provided type) and pass
it to method argument. This annotation converts input data from JSON/XML
format into Object. We provide this object as method parameter. In Spring
Boot application, @RequestBody annotation does all this behind the scene.
Below is the syntax to use @RequestBody:
@RequestBody ClassName objectName
For example, below code demonstrates the use of @RequestBody
@RestController
public class EmployeeRestController {
@PostMapping("/save")
public String saveEmp(@RequestBody Employee employee) {
return employee.toString();
}
}
Moreover, if we send invaild JSON/XML, like format is wrong, key-val are
wrong, then spring boot throws : 400 BAD REQUEST.
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-datafornmat-xml</artifactId>
</dependency>
If Producer REST application has no dependency for XML, still Request Header
has Accept : application/xml, then you will get Http Status: 406 Not
Acceptable.
If above XML dependency is not in place and trying to accept XML data
using @RequestBody, then you will get Http Status: 415 Unsupported
MediaTypes.
Generally, Http Status Codes come under below five categories.
Similarities:
self-describing (human readable) hierarchical (values within value)
can be parsed and used by lots of programming languages
can be fetched with XMLHttpRequest
Difference:
JSON doesn’t used end tag JSON is shorter
JSON is quicker to read write JSON can be used Arrays
Difference between Spring Frameworks vs Spring Boot Framework.
Why REST
Spring web Services follow to SOAP Spring web follow REST APIs in MVC
I would handle the exceptions with Spring’s @ControllerAdvice and
@ExceptionHandler. With this, I can send the status code and error
message in the response entity.
@RestController
Public class EmployeeController{
Public List <Employee> asList=new ArrayList();
@GetMapping(“/{id}”)
Employee getById(@PathVariable Long id){
Return asList.stream().filter(e ->
e.id=id).findFirst().orElseThrow(EmployeeNotFoundException::new );
}
}
public class EmployeeNotFoundException extends RuntimeException{
EmployeeNotFoundException(){
super(“Employee not found ”, HttpStatus.NOT_FOUND);
}
}
Any class annotated with @ControllerAdvice will become a controller-
advice class which will be responsible for handling exceptions. Under
this class, we make use of annotations provided as @ExceptionHandler,
@ModelAttribute, @InitBinder.
Spring MVC
Spring MVC is the primary web framework built on the Servlet API. It is build
on the popular MVC design pattern. MVC (Model-View-Controller) is a
software architecture pattern, which separates application into three areas:
model, view, and controller. The model represents a Java object carrying data.
The view represents the visualization of the data that the model contains. The
controller controls the data flow into model object and updates the view when
the data changes. It separates the view and model.
@RestController
Restful application
A RESTFul application follows the REST architectural style, which is used for
designing networked applications. RESTful applications generate HTTP
requests performing CRUD (Create/Read/Update/Delete) operations on
resources. RESTFul applications typically return data in JSON or XML format.