Spring annotations
Spring Core Annotations
Annotations related to Dependency Injection
@Autowired
- applied on fields, setter methods, and constructors. The @Autowired annotation injects object dependency implicitly.@Qualifier
- This annotation is used along with @Autowired annotation. When you need more control of the dependency injection process, @Qualifier can be used.@Primary
@Bean
- This annotation is used at the method level. @Bean annotation works with @Configuration to create Spring beans.@Lazy
- This annotation is used on component classes. By default all autowired dependencies are created and configured at startup. But if you want to initialize a bean lazily, you can use @Lazy annotation over the class.@Required
- This annotation is applied on bean setter methods. Consider a scenario where you need to enforce a required property. The @Required annotation indicates that the affected bean must be populated at configuration time with the required property.@Value
- This annotation is used at the field, constructor parameter, and method parameter level. The @Value annotation indicates a default value expression for the field or parameter to initialize the property with. Usually, it reads from application.property files.@Scope
- refer to spring scopes@Lookup
, etc.
Context Configuration Annotations
@Profile
- if you want Spring to use a@Component
class or a@Bean
method only when a specific profile is active@Import
@ImportResource
@PropertySource
, etc.
Spring Web Annotations
@EnableWebMvc
: Flags the application as a web application and activates key behaviors, such as setting up a DispatcherServlet. Spring Boot adds it automatically when it sees spring-webmvc on the classpath.@Controller
- used for traditional Spring controllers. It has been part of the framework for a very long time.@RestController
- Spring 4.0 introduced the@RestController
annotation in order to simplify the creation of RESTful web services. It’s a convenient annotation that combines@Controller
and@ResponseBody
, which eliminates the need to annotate every request handling method of the controller class with the@ResponseBody
annotation. How the response is generated is the main difference between@Controller
and@RestController
- the@RestController
also defines@ResponseBody
by default.@ModelAttribute
@CrossOrigin
- Request Handling Annotations
-
@RequestMapping
@RestController public class GreetingController { private static final String TEMPLATE = "Hello, %s!"; @RequestMapping("/greeting") public HttpEntity<Greeting> greeting( @RequestParam(value = "name", defaultValue = "World") String name) { Greeting greeting = new Greeting(String.format(TEMPLATE, name)); greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel()); return new ResponseEntity<>(greeting, HttpStatus.OK); } }
This example does not specify GET versus PUT, POST, and so forth. By default
@RequestMapping
maps all HTTP operations. You can use@GetMapping
or@RequestMapping(method=GET)
to narrow this mapping. -
@RequestBody
-
@PathVariable
-
@RequestParam
-
Composed
@RequestMapping
variants - Spring 4.3 introduced new annotations which serve the same purpose as@RequestMapping
having predefinedmethod
(HTTP verb) value. Those annotations are actually themselves meta-annotated with@RequestMapping
with the related value ofmethod
element.@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
What is the necessity for these composed variants?
consumes
element is not defined for@GetMapping
as no data is consumed in the Get request handler, but it does for POST, PUT and DELETE requests.consumes
is defined for@RequestMapping
. The advantage of these kind of approaches is, it reduces the configuration metadata on the application side and the code is more readable.@Slf4j @RequiredArgsConstructor @RestController public class S3BucketStorageController { private final S3StorageService service; @PostMapping("/file/upload") public ResponseEntity<String> uploadFile(@RequestParam("fileName") String fileName, @RequestParam("file") MultipartFile file) { return new ResponseEntity<>(service.uploadFile(fileName, file), HttpStatus.OK); } @DeleteMapping("/file/delete") public ResponseEntity<String> deleteFile(@RequestParam("fileName") String fileName) { return new ResponseEntity<>(service.deleteFile(fileName), HttpStatus.OK); } @GetMapping("/file/download") public ResponseEntity<String> downloadFile(@RequestParam("fileName") String fileName, @RequestParam("rawContent") boolean rawContent) { return new ResponseEntity<>(service.downloadFile(fileName, rawContent), HttpStatus.OK); } @GetMapping("/list/files") public ResponseEntity<List<String>> getListOfFiles() { return new ResponseEntity<>(service.listFiles(), HttpStatus.OK); } @GetMapping("/presignedurl") public ResponseEntity<String> getPresignedUrl(@RequestParam("fileName") String fileName) { return new ResponseEntity<>(service.generatePUTPresignedURL(fileName), HttpStatus.OK); } }
-
- Response Handling Annotations
@ResponseBody
@ExceptionHandler
@ResponseStatus
- This is useful when we want to indicate that the response will not have any content (return type is
void
).@DeleteMapping(value = HERO_MAPPING) @ResponseStatus(value = HttpStatus.NO_CONTENT) public void delete(@PathVariable Long heroId) { heroService.delete(heroId); }
- If the response doesn’t return any content, we shouldn’t be returning a
200
. We should be returning a204
. This annotation sets the response code to204
.
- This is useful when we want to indicate that the response will not have any content (return type is
Spring Boot Annotations
@SpringBootApplication
- This annotation is used to mark the main class of a Spring Boot application. It encapsulates@Configuration
,@EnableAutoConfiguration
, and@ComponentScan
annotations with their default attributes. It also encapsulates@EnableWebMvc
when the springboot app has spring-webmvc on the classpath (spring-boot-starter-web
starter parent in pom.xml). The main() method in the class with this annotation uses Spring Boot’s SpringApplication.run() method to launch an application.@EnableAutoConfiguration
- Tells Spring Boot to start adding beans based on classpath settings, other beans, and various property settings.- Auto-Configuration Conditions
@ConditionalOnClass
, and@ConditionalOnMissingClass
@ConditionalOnBean
, and@ConditionalOnMissingBean
@ConditionalOnProperty
@ConditionalOnResource
@ConditionalOnWebApplication
and@ConditionalOnNotWebApplication
@ConditionalExpression
@Conditional
Spring Scheduling Annotations
@EnableAsync
- Used to enable asynchronous functionality in Spring.@EnableScheduling
@Async
@Scheduled
@Schedules
Spring Data Annotations
- Common Spring Data Annotations
@Transactional
1, Spring Data JPA - transactions@NoRepositoryBean
- The purpose of the
@NoRepositoryBean
annotation is to prevent Spring from treating that specific interface as a repository by itself. TheJpaRepository
interface (Spring interface) has this annotation because it isn’t a repository itself, it’s meant to be extended by your own repository interfaces, and those are the ones that should be picked up.
- The purpose of the
@Param
@Id
@Transient
- To ignore a JPA field during persistence
- Essentially a “@Ignore” type annotation with which I can stop a particular field from being persisted.
- But if we use this annotation, jackson will not serialize the field when converting to JSON.
If you need mix JPA with JSON(omit by JPA but still include in Jackson) use @JsonInclude :
You can also use JsonInclude.Include.NON_NULL and hide fields in JSON during deserialization when token == null:
@JsonInclude() @Transient private String token;
@JsonInclude(JsonInclude.Include.NON_NULL) @Transient private String token;
@CreatedBy
,@LastModifiedBy
,@CreatedDate
,@LastModifiedDate
- Spring Data JPA Annotations
@Query
@Procedure
@Lock
@Modifying
@EnableJpaRepositories
- Spring Data Elasticsearch Annotations
@Document
- specifies the index name - the index into which the entities are saved@Id
- makes the annotated field the_id
of the document. The unique identifier in this index. Theid
field has a constraint of 512 characters.@Field
- configures the type of a field. We can also set the name to a different field name.@Query
@EnableMongoRepositories
@MultiField
- Indexes the field in several ways.@InnerField
- Describes additional indexing of the title field.
- Spring Data Mongo Annotations
@Document
@Field
@Query
@EnableMongoRepositories
Spring Bean Annotations
@ComponentScan
- Tells Spring to look for other components, configurations, and services in the package with the class containing the @SpringBootApplication annotation, letting it find the Controller class. This annotation is used with @Configuration annotation to allow Spring to know the packages to scan for annotated components. @ComponentScan is also used to specify base packages using basePackageClasses or basePackage attributes to scan.basepackages
- When using a library, use this to tell the Spring to include the classes from that library in the classpath when starting the application.@ComponentScan(basePackages = { "com.mycompany.the.package.name.of.the.current.application", "the.base.package.name.of.the.library" })
@Configuration
- Tags the class as a source of bean definitions for the application context. This annotation is used on classes which define beans. @Configuration is an analog for XML configuration file – it is configuration using Java class. Java class annotated with @Configuration is a configuration by itself and will have methods to instantiate and configure the dependencies.- Stereotype Annotations
@Component
- a class-level annotation. Used to denote a class as a Component. We can use @Component across the application to mark the beans as Spring’s managed components. A component is responsible for some operations. Spring framework provides three other specific annotations to be used when marking a class as a Component.@Service
- Indicates that the class with this annotation is holding the business logic. Used in the service layer. Sometimes, utility classes can be marked as Service classes.@Repository
- We specify a class with@Repository
to indicate that they’re dealing with CRUD operations, usually, it’s used with DAO (Data Access Object) orRepository
implementations that deal with database tables.- It is indeed not necessary to put the
@Repository
annotation on interfaces that extendJpaRepository
; Spring recognises the repositories by the fact that they extend one of the predefinedRepository
interfaces.
- It is indeed not necessary to put the
@Controller
- We specify a class with @Controller to indicate that they’re front controllers and responsible to handle user requests and return the appropriate response. It is mostly used with REST Web Services.
Spring test annotations
@SpringBootTest
- tells Spring Boot to look for a main configuration class (one with @SpringBootApplication, for instance) and use that to start a Spring application context.@LocalServerPort
- @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) starts the server with a random port (useful to avoid conflicts in test environments) and the random port is injected into the test with this annotation.@AutoConfigureMockMvc
- To ask spring to inject Spring’s MockMvc into the test case.@WebMvcTest
- Narrow down the tests to only the web layer by using@WebMvcTest
(instead of using@AutoConfigureMockMvc
). In an application with multiple controllers, you can even ask for only one to be instantiated by using, for example,@WebMvcTest(HomeController.class)
.
Reading material
https://www.geeksforgeeks.org/spring-framework-annotations/
https://springframework.guru/spring-framework-annotations/
https://www.digitalocean.com/community/tutorials/spring-annotations