Annotations in Spring

hemasai jammana
4 min readApr 6, 2023

--

In the earlier articles, we have seen the basics of the spring framework like spring container and what is dependency injection, what is Spring bean, and the different attributes of a spring bean.
Now it is time to move to the next way of the configuration of metadata to the spring container.

Spring

As we already know there are 4 ways to configure the metadata (bean information) to the spring container.
1. XML file based
2. Annotations based
3. Pure Java code base
4. Spring Boot Auto Driven

Now we will see the Annotation based configuration and a few of the annotations. We may be using the annotations but how can the spring container come to know and deal with the annotations for that we need to inform the spring container through XML file adding <context:annotation-config/>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<context:annotation-config/>

</beans>

<context:annotation-config/> This will check for the required beans which are defined.

@Required:
When we are working on constructor injection if any parameter is missing we will get an exception but for setter injection, we will not get any exception.
To provide this functionality we can use the @Required annotation on setters.

@Autowired:
As we have already seen what is Auto wiring earlier, we know we can do it in three ways bytype, byName, and constructor.
This Autowired also does the same byType, byName, and constructor mode of auto wiring.
By Default auto wiring on byType.

AutoWire using ByName:
If more than one bean of the same type is found then we will get an exception. There are 3 classes that are implementing courier class.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd">

<context:annotation-config/>

<!-- Dependent bean -->
<bean id="amazon" class="src.courier.Amazon"/>
<bean id="dtdc" class="src.courier.Dtdc"/>
<bean id="bluedart" class="src.courier.BlueDart"/>

<!-- target bean -->
<bean id="flip" class="src.services.Flipkart"/>
public class Flipkart {

@Autowired
private Courier courier;

..................,,,
}

In the above code as we have 3 beans of courier type so we will get an exception. We can rectify the above using primary in XML file or we can use @Qualifer on top of the courier instance.

    <bean id="amazon" class="src.courier.Amazon"/>
<bean id="dtdc" class="src.courier.Dtdc"/>
<bean id="bluedart" class="src.courier.BlueDart" primary="true"/>
public class Flipkart {

@Autowired
@Qualifier("bluedart")
private Courier courier;

..............,,,
}

If we use both the @Qualifier and primary = “true”, Qualifier if given high preference.

AutoWire using ByName:

<!-- Dependent bean -->
<bean id="amazon" class="src.courier.Amazon"/>
<bean id="dtdc" class="src.courier.Dtdc"/>
<bean id="courier" class="src.courier.BlueDart"/>

<!-- target bean -->
<bean id="flip" class="src.services.Flipkart"/>
public class Flipkart {

@Autowired
private Courier courier;

..................,,,
}

As we are having only one bean with the courier as name auto wiring will happen using By Name.

AutoWire using Constructor:
We will be using Autowired annotation at the constructor level and if multiple beans we will use the Qualifier

public class Flipkart {
private Courier courier;

@Autowired
public Flipkart(@Qualifier("bluedart") Courier courier) {
this.courier = courier;
}
}

Setter Injection using Autowired:

public class Flipkart {

private Courier courier;

@Autowired
public void setCourier(@Qualifier("bluedart") Courier courier) {
this.courier = courier;
}
}

@PostConstruct:
We can write our own custom init methods and annotate with PostConstruct then the spring container will execute that first and then it process to the business logic.

@PreDestroy:
We can also write the same destroy method to clear all the data before the container leaves the particular class and annotate with the PreDestroy.

Stereotype Annotations:

In Spring Framework, stereotype annotations are used to indicate the roles of specific classes in the application. Stereotype annotations are a type of metadata that provide hints to Spring about how to handle certain classes, and they can be used to simplify the configuration and management of Spring components.
Spring can automatically detect stereotyped classes and register bean definitions with the ApplicationContext.
To auto-detect these classes and register the beans we need to provide the below XML file in which we provide a base package to scan for these stereotyped classes. <context:component-scan base-package=”org.example”/>

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="org.example"/>

</beans>

We have the following annotations in spring:
1. Component
2. Controller
3. Service
4. Repository

  1. Component:
    This annotation is used to mark a class as a Spring component, which means it will be scanned and registered with the Spring container as a bean. This annotation can be used with any class, but it is typically used with domain objects, utility classes, and other non-specific classes.
  2. Controller:
    Component
    +
    This annotation is used to mark a class as a Spring MVC controller, which means it will be scanned and registered with the Spring container as a bean. This annotation is typically used with classes that handle HTTP requests and responses.
  3. Service:
    Component +
    This annotation is used to mark a class as a Spring service, which means it will be scanned and registered with the Spring container as a bean. This annotation is typically used with classes that perform business logic and data access operations.
  4. Repository:
    Component +
    This annotation is used to mark a class as a Spring repository, which means it will be scanned and registered with the Spring container as a bean. This annotation is typically used with classes that perform data access operations, such as querying a database.

Advantages:
- code readability and maintainability will be good.
- save a lot of time adding all the configuration.
- we can mention the clear role of a particular class.

We will be seeing more annotations in the coming posts.

Please do follow for more articles and learn with me.
Special Thanks to Nitin M who made these all concepts very easy.

--

--

hemasai jammana

Software Engineer, learning and exploring new technologies.