Spring: Core annotations

 2021-07-12

Spring: Core annotations

Spring dependency injection is one of the core features of Spring Framework that enables application-wide instantiation, management, and assembly of beans. To use these features we have to go through the annotations provided in the org.springframework.beans.factory.annotation and org.springframework.context.annotation package. They can be considered the core annotations of Spring that we will learn together shortly.

 

1. Spring: Core annotations


1.1. @Autowired

We use @Autowired to annotate a dependency that will be resolved by Spring and injected from the Spring IoC container. We can use @Autowired with the constructor, setter, or on a specific property.

@Autowired with the constructor

@Autowired with the setter

@Autowired on the property

With all of the above methods, Spring will try to find a bean with a data type Engine to inject into the Car class. Besides, @Autowired has a required attribute whose default value is TRUE, when Spring cannot find a corresponding bean to inject it will throw an exception.

Note: Since Spring version 4.3 we do not need @Autowired annotation on the constructor, Spring will understand and find the corresponding dependencies to inject. However, if there is more than 1 constructor, we need to specify @Autowired on the constructor used to declare the dependencies to be used in the Class.

1.2. @Bean

@Bean is used to annotate a method used to initialize a Spring bean.

Spring will call these methods to initialize a bean with the corresponding data type as needed. By default, the name of the bean will be the same as the name of the method, if you want to change the name of the bean, you can pass a parameter to the @Bean annotation to specify the name of the bean.

Note: All methods annotated with @Bean must be in @Configuration classes.

1.3. @Qualifiter

We usually use @Qualifier with @Autowired to provide Bean ID or Bean Name that we want to use in case there is more than 1 bean with the same data type in the Spring IoC container.

For example, in case we have 2 implementations of an interface

In this case, we have to provide the Bean Name to tell Spring which dependency you want Spring to inject. We can provide Bean Name with @Qualifier annotation as follows:

Or if we use the setter injection

1.4. @Required

@Required on the setter method to annotate the dependencies we want to include via XML.

Otherwise, BeanInitializationException will be thrown.

1.5. @Value

If we can use @Value to put the value of a property into the Bean. It is compatible with the constructor, setter, and field injection.

However, with the above usage, the values of the properties are constant and cannot be changed during the app's run.

Usually, @Value is used with a key defined in the .properties or .yaml configuration files with the corresponding value. Properties annotated with @Value({key}) will carry the corresponding value in the configuration files.

For example, in application.properties the following key-value pairs:

We can pass the value of engine.fuelType to an attribute like this:

1.6. @DependsOn

We can use this annotation on a bean to tell Spring that another bean must be initialized before instantiating it with the bean name specified in @DependsOn.

1.7. @Lazy

Using @Lazy will cause Spring to only initialize a bean when needed. It means that when there is a request to the app that needs to use this bean. Because default Spring will initialize all singleton beans at application launch time.

Using @Lazy in different places will have different effects such as:

  • Combined with the @Bean annotation on a method to delay Spring calling the method to initialize the bean at program launch.
  • In common with @Configuration class and all methods annotated with @Bean annotation will be delayed.
  • On @Component class will delay Spring scan and initialization.
  • On an @Autowired constructor, setter, or field to load dependencies as needed.

The example creates a @Configuration that is initialized only when needed and a @Bean method that initializes the bean as soon as this @Configuration is initialized.

1.8. @Primary

Sometimes we have many beans of the same data type simultaneously. When declaring the dependency we need to specify which bean to use. In this case, we can solve this by using @Qualifier with the name of the bean to use. However, it is annoying to always have to declare them with the @Qualifier annotation.

Suppose there are 2 beans with the same data type, but almost we only use one bean by default, and the other bean is rarely used. Then we can annotate the heavily used bean with the @Primary annotation. Now if the dependency declaration doesn't have @Qualifier, then @Primary bean will be used.

In the above example, the Driver will use Car bean while Biker will use the Bike bean.

1.9. @Scope

@Scope is used to define the scope of a @Component class or a @Bean method in Spring. Possible scopes are singleton, prototype, request, session, globalSession, and some custom scopes,

2. Context Configuration Annotations


We have some annotations used to configure the application context.

2.1. @Profile

If we want Spring to use @Component class and @Bean method with certain profiles. We can annotate them @Profile annotation specifying that they are initialized only when the respective profile is active.

2.2. @Import

We can use specific @Configuration classes without component scanning with this annotation. We can provide those classes with @Import's value argument:

2.3. @ImportResource

We can import XML configurations with this annotation. We can specify XML file locations with the location argument or by its alias, the value argument:

2.4. @PropertySource

With this annotation, we can define properties files for application settings

@PropertySource leverages Java 8's repeating annotations feature, which means we can mark a class with it multiple times:

2.5. @PropertySources

We can use this annotation to specify multiple @PropertySource configurations:

Note: As of Java 8, we can achieve the same thing with repeated comments as described above.

 

If you are considering offshore development, please feel free to contact us.

Here is our contact information.

Account Manager: Quan (Japanese/English available)

Phone number: (+84) 2462 900 388

Email: contact@hachinet.com

Please feel free to contact us for consultation/application by phone.

Click here for more information ▶