Core Spring Framework Annotations

Anish Antony
Apr 22 · 7 min read

The spring supports a large set of annotations for handling different situations. Over this article, we are exploring the annotations in the spring core framework.

Photo by Victoria Strukovskaya on Unsplash

Over this article, we are discussing the spring core annotations such as @Autowire, @Qualifier, @Configuration, @Bean, @ComponentScan, @Lazy, and @Value. We will cover all these annotations with examples.

@Autowire

From Spring 2.5, the framework introduced annotations-driven Dependency Injection. The main annotation that comes as part of this feature is @Autowired. It allows Spring to resolve and inject collaborating beans into our bean.

In spring there are two types of autowiring. Those are

  • Autowiring by type.
  • Autowiring by name.

Autowiring by type: @Autowired by type uses the class type to autowire the spring boot bean class. The bean is autowired based on the type of the variable.

Autowiring by name: For Autowiring by name, the name of the variable is used for the dependency injection. The name of the authoring variable should be the same as the name of the class or the bean name configured in the @Component annotation.

Let's go for an example for both.

In the above example, the shape interface is implemented by two classes Circle and Rectangle. So we can say both are instances of Shape or both shape. It made Rectangle and Circle as spring beans using the annotation @Component. Now let's see how to autowire these beans in another class.

Here in ShapeService class, it is autowring the shape Rectangle in two ways.

  • Here in the first @Autowiring, the variable rectangle is autowired based on the name of the variable. Here when the spring checks the type of the variable, he can see it is Shape. But there are two shape implementations are there Rectangle and Circle. So spring doesn't get a proper solution for what component need to autowire. Then the spring check the name of the variable(rectangle) and find out any Shape component with the same name is available. Yes…The Rectangle component is available. So the spring will inject the property with rectangle component.
  • In the second @Autowiring, the type of property is Rectangle. So the spring directly injects the Rectangle component to the property myRectangle.

We already discussed @Autowired annotation in properties in the above example. Let's discuss the other three usages of the @Autowired annotation.

@Autowired annotation on constructors

The @Autowired annotation is used in the class constructor method. The value of the constructor argument is passed automatically while the instance class is created. In the spring boot, @Autowired assigns values to the constructor. This is an alternative to using the @Autowired annotation in properties.

The above shows an example of Autowring using the constructor. Here the constructor parameter circle is autowired based on name and the parameter shape2 autowired based on type.

@Autowired Annotation on Setters

Similar to properties autowiring. It is able to implement the @Autowired annotation on the setter method. The below example shows an example for setter-based autowiring.

Here in setShape method, it is autowiring based on the parameter name (Circle component). In setShapeTwo the method, it is autowiring based on the parameter type(Rectangle Component).

@Qualifier

The @Qualifier annotation helps to make more control over @Autowire an annotation. The @Qualifier annotation help in the issue to choose the correct bean for the dependency injection.

This annotation is used along with @Autowired annotation. When you need more control of the dependency injection process, @Qualifier can be used. @Qualifier can be specified on individual constructor arguments or method parameters. This annotation is used to avoid confusion that occurs autowiring by name injection.

Let's see how the @Qualifier annotation resolves autowiring conflicts.

In the above example, you can see there are two implementations for the Shape interface which are Circle and Rectangle. The classes Circle and Rectangle declared with @Component annotation, which means they are spring beans.

The above line code snippet autowiring the created Shape components. But the spring got confused here because spring can't find out which component autowire to these fields myShapeOne and myShapeTwo. Autowiring by type or name does not work here. So the spring throws below exception for the above code snippet.

Field myShapeOne in com.lici.spring.bean.shape.ShapeService required a single bean, but 2 were found:
....
Field myShapeTwo in com.lici.spring.bean.shape.ShapeService required a single bean, but 2 were found:

@Qualifier annotation helps to resolve this. The @Qualifier annotation can used with the @Autowired annotation and used to specify which object exactly want to autowire with the fields.

In the below code with the help of @Qualifier annotation, it is mentioning the myShapeOne field autowire with the Circle component and myShapeTwo field autowire with Rectangle component.

@Configuration

Spring @Configuration annotation is used to declare more than one bean in a class with the help of @Bean annotation. @Configuration annotation is a class-level annotation and normally in a configuration bean it contains 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.

Use @Configuration annotation on top of any class to declare that this class provides 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.

In the above code snippet, it is declared the Rectangle and Circle implementation. But those do not spring beans because it is not declared with the @Component or any spring related annotation on those classes. The classes are completely free from the spring annotation. Using following snippet it is able to add those classes to spring beans without touching the classes.

From the above code snippet, it is added the Rectangle and Circle as part of spring beans. Next autowire those beans, which explains in below code snippet.

So we can conclude, one of the biggest benefits of @Configuration annotation is it is able to implement @Bean annotation inside it.

@Bean

This annotation is used at the method level. @Bean the annotation works with @Configuration to create Spring beans. As mentioned earlier, @Configuration will have methods to instantiate and configure dependencies. Such methods will be annotated with @Bean. We already saw the examples of @Bean annotation as part of @Configuration annotation examples.

@ComponentScan

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.By default, the @ComponentScan annotation will scan for components in the current package and all its sub-packages.

In the above example, the class AdditionalService is placed on the different package which is entirely different from the main class package. Spring not detect the component AdditionalService because it is not as part of the Main class base package or its subpackage. Here comes the importance of @ComponentScan annotation. Using the annotation it is able to specify what are packages needs to scan.

@Lazy

The Spring framework, by default, initializes all singleton beans eagerly at the application startup and puts them in the application context. However, in some cases we need to create beans whenever required, but not at the application startup or bootstrapping application context time. In Spring, we can achieve this by using @Lazy annotation.

In the below code snippet it is added the lazy annotation for the LazyClass component.

After the server startup, you can see that it is not printed the LazyClass constructor code in the server startup code which means it is not initialized in the startup.

In the below code snippet the runner method executes after the server startup. So here it is trying to access the LazyClass bean from the ApplicationContext after server startup. when the system calls ctx.getBean(LazyClass.class) then only the system initialize the LazyClass bean

Here follows the output of the above code snippet.

Also, it is able to apply the @Lazy annotation on top of the configuration class so that all the beans inside the configuration class become initialized lazily.

@Lazy can apply on the @Component annotated class like follows.

When the @Lazy annotation is present together with the @Component annotation on class level, then the component will not be eagerly created by the container, but when the component is first requested. Together with the @Autowired injection point, you need to mark it with @Lazy annotation.

It should need to make the component as well as the autowiring field is mentioned with @Lazy annotation. Then only the component loaded lazily. The below example explains that.

@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. As the @Autowired annotation tells Spring to inject an object into another when it loads your application context, you can also use @Value annotation to inject values from a property file into a bean’s attribute. It supports both #{…} and ${…} placeholders.

The below example shows reading different values from a properties file.

Here the below code explains getting properties from the above file in different ways.

Hope you enjoyed this article…

Javarevisited

Medium’s largest Java publication, followed by 11300+ programmers. Follow to join our community.

Anish Antony

Written by

Fullstack Developer | Blogger | Experience on Java, Python, React, Angular, Golang | http://www.behindjava.com

Javarevisited

A humble place to learn Java and Programming better.

Anish Antony

Written by

Fullstack Developer | Blogger | Experience on Java, Python, React, Angular, Golang | http://www.behindjava.com

Javarevisited

A humble place to learn Java and Programming better.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store