SPRING ANNOTATION: @Qualifier
Aids Spring in resolving which bean to select.
In some instances, there may be multiple candidates for a dependency. This causes a NoUniqueBeanDefinitionException:
//Without @Qualifier: NoUniqueBeanDefinitionException:
//With @Qualifier: no NoUniqueBeanDefinitionException:
SPRING ANNOTATION: @Service
The @Service annotation — as the name implies — denotes that a bean is a service.
In general, the concept of service in enterprise applications is vague, but in the context of a Spring application, a service is any class that provides methods to interact with domain logic or external components without maintaining state that changes the overall behavior of the service. For example, a service may act on behalf of an application to obtain documents from a database or obtain data from an external REST API.
While there is no definitive rule about the state of a service, services generally do not contain state in the way that domain objects do. For example, a REST client, cache, or connection pool would not be considered the state of a service in the same way that a name, address, and social security number would be regarded as the state of a domain object. In practice, @Service and @Component are often used interchangeably due to the all-encompassing definition of a service.
SPRING ANNOTATION: @ComponentScan
@ComponentScan does not execute any logic. Instead, it is simply a marker that denotes that it is has to be scan by Spring.
To instruct Spring which packages to scan, we use the @ComponentScan annotation:
By default — if no arguments are supplied to the @ComponentScan annotation — the package that contains the configuration, and all its subpackages, are scanned. To specify a package or set of packages, the basePackages field is used:
In the above example, Spring would scan the package com.example.foo and all of its subpackages for eligible components. If only one base package is provided, the @ComponentScan annotation can be simplified to @ComponentScan("com.example.foo"). If more than one base package is required, the basePackages field can be assigned a set of strings:
SPRING ANNOTATION: @Bean
to declare a bean out of Spring scanning
@Bean is a method-level annotation and a direct analog of the XML element.
@Bean is useful when we do not have access to the source code for the class or the class exists in a package that is not part of the component scanning process.
@Bean is used to declare a single bean, rather than letting Spring do it automatically as in case of Component.
It decouples the declaration of the bean from the class definition, and lets you create and configure beans exactly how you choose.
@Bean are used at method level and can be configured as required
eg:
For comparison sake, the configuration above is exactly equivalent to the following Spring XML:
SPRING ANNOTATION: @Autowired
@Autowired informs the Spring Framework which fields or constructor parameters are expecting to be injected.
When applied to fields:
For testing purposes, if you want to fill bar field, it is convenient to add the @Autowired annotation to a constructor that accepts a Bar parameter and assigns it to the bar field:
SPRING ANNOTATION: @Repository
While @Service is intended for more a general purpose, the @Repository annotation is a specialization of the @Component annotation that is designed for components that interact with data sources, such as databases, and Data Access Objects (DAOs).
It is a a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects.
SPRING ANNOTATION: @Configuration
Due to the enormous scale of the Spring Framework,a level of developer-supplied configuration is needed.
For example, if we wish to define a set of beans that can be used for autowiring, we must inform Spring with some configuration mechanism.
Spring provides this mechanism through the aptly named @Configuration annotation.
When this annotation is applied to a class, Spring treats that class as if it contains configuration information that can be used to parameterize the framework.
According to the official Spring @Configuration documentation:
Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, for example:
SPRING ANNOTATION: @Component
How to know which beans are candidates to be injected into other beans? To answer this question, Spring provides the @Component annotation. Applying this annotation to class informs Spring that the class is a component and an object of this class can be instantiated and injected into another component. The @Component interface is applied to a class in the following manner:
SPRING ANNOTATION: @RequestMapping
instructs Spring to create a web endpoint that maps to the annotated method.
This mapping informs Spring that a specific HTTP verb and path should be mapped to a specific method.
Spring also includes four additional annotations that can be used to simplify the creation of @RequestMapping methods:
- @GetMapping
- @PostMapping
- @PutMapping
- @DeleteMapping
The @RequestMapping annotation can also be applied to the controller itself, which sets the root path for the entire controller. For example, the following controller creates a GET endpoint at the /foo path and another POST endpoint at /foo/bar:
SPRING ANNOTATION: @Controller
Spring Model-View-Controller (MVC) is one of the most popular portions of the Spring Framework and allows developers to easily create REST APIs using the @Controller annotation. This annotation, when applied to a class, instructs the Spring Framework that the class should be treated as a part of the web interface for the application.
Endpoints are created in this class by applying the @RequestMapping annotation to the methods of that class. For example:
This would create an endpoint that listens on the /foo path for GET requests and returns a list of all Foo objects to the caller. The @Controller annotation is a potent part of the Spring Framework and one that instructs the Spring Framework to create large and complex web service implementations on our behalf.
SPRING ANNOTATION: @PathVariable
―Obtains the value of the path variable.
For example, /foo/1. We capture the path variable by enclosing the variable name with curly braces and applying the @PathVariable annotation such that '1' matches the name of the variable captured in the path:
―If the name of the parameter exactly matches the name of the captured variable in the path, no value needs to be supplied to @PathVariable annotation:
―If we except the value of the ID path variable to be an integer, we could change the data type of the id parameter to int:
But if a value, such as the string baz, is supplied in the path (i.e., /foo/baz), an error will occur.
SPRING ANNOTATION: @RequestParam
Apart from capturing path variables, we can also capture query parameters using the @RequestParam annotation.
The @RequestParam decorates a parameter to the handler method in the same manner as the @PathVariable annotation,
but the value supplied to the @RequestParam annotation matches the key of the query parameter.
For example, if we expect that an HTTP GET call will be made to a path of /foo?limit=100, we can create the following controller to capture the limit value:
Just as with @PathVariable, the value supplied to the @RequestParam annotation can be omitted, and the name of the parameter will be used by default.
Likewise, Spring will coerce the value of the captured query parameter into the type of the parameter, if possible (in the case above, to int).
SPRING ANNOTATION: @RequestBody
In cases where a request body is supplied in a call —with POST or PUT— Spring provides the @RequestBody annotation. @RequestBody annotation is applied to a parameter of the handler method. Spring will then deserialize the supplied request body into the type of the parameter. E.G, we can create a new Foo with an HTTP call that has a request body:
We can then create a class that encompasses fields that match the expected request body and create a handler method that captures this request body: