Spring Core Annotations with Examples

In this quick article, we will discuss Spring core annotations that are used in Spring Dependency Injection, Java-based configuration, Annotation-based configuration, and Spring IOC. 

YouTube Video - Spring Core Annotations

15 Important Spring Core Annotations

Let's list all known Spring core annotations.

@Autowired Annotation with Example

Spring @Autowired annotation is used for the automatic injection of beans.

We can use @Autowired annotation with a constructor, setter, or field injection.
 
Constructor Injection:
@RestController
public class CustomerController {
    private CustomerService customerService;
 
    @Autowired
    public CustomerController(CustomerService customerService) {
        this.customerService = customerService;
    }
}
Setter Injection:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {
    private CustomerService customerService;
 
    @Autowired
    public void setCustomerService(CustomerService customerService) {
        this.customerService = customerService;
    }
}
Field Injection:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class CustomerController {
    @Autowired
    private CustomerService customerService;
}
For more details visit our articles about @Autowired and Guide to Dependency Injection in Spring.

@Bean Annotation with Example

@Bean annotation indicates that a method produces a bean to be managed by the Spring container. The @Bean annotation is usually declared in the Configuration class to create Spring Bean definitions.

The following is a simple example of a @Bean method declaration:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.companyname.projectname.customer.CustomerService;
import com.companyname.projectname.order.OrderService;

@Configuration
public class Application {

    @Bean
    public CustomerService customerService() {
        return new CustomerService();
    }

    @Bean
    public OrderService orderService() {
        return new OrderService();
    }
}
The preceding configuration is exactly equivalent to the following Spring XML:
<beans>
        <bean id="customerService" class="com.companyname.projectname.CustomerService"/>
        <bean id="orderService" class="com.companyname.projectname.OrderService"/>
</beans>
Read more about @Bean annotation on Spring @Bean Annotation with Example.

@Qualifier Annotation with Example

@Qualifier annotation is used in conjunction with Autowired to avoid confusion when we have two or more beans configured for the same type.
Example: Consider EmailService and SMSService classes implements a single MessageService interface.
Create a MessageService interface for multiple message service implementations.
public interface MessageService {
    public void sendMsg(String message);
}
Create implementations - EmailService and SMSService.
public class EmailService implements MessageService{

    public void sendMsg(String message) {
         System.out.println(message);
    }
}
public class SMSService implements MessageService{

    public void sendMsg(String message) {
         System.out.println(message);
    }
}
It's time to see the usage of @Qualifier annotation.
public interface MessageProcessor {
    public void processMsg(String message);
}

public class MessageProcessorImpl implements MessageProcessor {

    private MessageService messageService;

    // setter based DI
    @Autowired
    @Qualifier("emailService")
    public void setMessageService(MessageService messageService) {
        this.messageService = messageService;
    }
 
    // constructor based DI
    @Autowired
    public MessageProcessorImpl(@Qualifier("emailService") MessageService messageService) {
        this.messageService = messageService;
    }
 
    public void processMsg(String message) {
        messageService.sendMsg(message);
    }
}
Read more about this annotation on Spring @Qualifier Annotation Example.

@Required Annotation with Example

The @Required annotation is method-level annotation and is applied to the setter method of a bean.
This annotation simply indicates that the setter method must be configured to be dependency-injected with a value at configuration time.
For example, @Required on setter methods to mark dependencies that we want to populate through XML:
@Required
void setColor(String color) {
    this.color = color;
}
<bean class="com.javaguides.spring.Car">
    <property name="color" value="green" />
</bean>
Otherwise, BeanInitializationException will be thrown.

@Value Annotation with Example

Spring @Value annotation is used to assign default values to variables and method arguments. We can read spring environment variables as well as system variables using @Value annotation.
Spring @Value annotation also supports SpEL. Let’s look at some of the examples of using @Value annotation.
Examples: We can assign a default value to a class property using @Value annotation.
@Value("Default DBConfiguration")
private String defaultName;
@Value annotation argument can be a string only, but spring tries to convert it to the specified type. The below code will work fine and assign the boolean and integer values to the variable.
@Value("true")
private boolean defaultBoolean;

@Value("10")
private int defaultInt;
Spring @Value – Spring Environment Property
@Value("${APP_NAME_NOT_FOUND}")
private String defaultAppName;
Assign system variables using @Value annotation.
@Value("${java.home}")
private String javaHome;
 
@Value("${HOME}")
private String homeDir;
Spring @Value – SpEL
@Value("#{systemProperties['java.home']}")
private String javaHome;

@DependsOn Annotation with Example

The @DependsOn annotation can force the Spring IoC container to initialize one or more beans before the bean which is annotated by @DependsOn annotation.
The @DependsOn annotation may be used on any class directly or indirectly annotated with @Component or on methods annotated with @Bean.
Example: Let's create FirstBean and SecondBean classes. In this example, the SecondBean is initialized before the bean FirstBean.
public class FirstBean {

    @Autowired
    private SecondBean secondBean;
}

public class SecondBean {
    public SecondBean() {
        System.out.println("SecondBean Initialized via Constuctor");
    }
}
Declare the above beans in java based configuration class.
@Configuration
public class AppConfig {

    @Bean("firstBean")
    @DependsOn(value = {
        "secondBean"
    })
    public FirstBean firstBean() {
        return new FirstBean();
    }

    @Bean("secondBean")
    public SecondBean secondBean() {
        return new SecondBean();
    }
}
Read more about @DependsOn annotation on Spring - @DependsOn Annotation Example.

@Lazy Annotation with Example

By default, the Spring IoC container creates and initializes all singleton beans at the time of application startup. We can prevent this pre-initialization of a singleton bean by using the @Lazy annotation.
The @Lazy annotation may be used on any class directly or indirectly annotated with @Component or on methods annotated with @Bean.
Example: Consider we have below two beans - FirstBean and SecondBean. In this example, we will explicitly load FirstBean using @Lazy annotation.
public class FirstBean {
    public void test() {
        System.out.println("Method of FirstBean Class");
    }
}
public class SecondBean {
    public void test() {
        System.out.println("Method of SecondBean Class");
    }
}
Declare the above beans in java based configuration class.
@Configuration
public class AppConfig {

    @Lazy(value = true)
    @Bean
    public FirstBean firstBean() {
        return new FirstBean();
    }

    @Bean
    public SecondBean secondBean() {
        return new SecondBean();
    }
}
As we can see, bean secondBean is initialized by the Spring container while bean firstBean is initialized explicitly.
Read more about @Lazy annotation with a complete example on Spring - @Lazy Annotation Example.

@Lookup Annotation

A method annotated with @Lookup tells Spring to return an instance of the method’s return type when we invoke it.
Detailed information about the annotation can be found in Spring @LookUp Annotation.

@Primary Annotation with Example

We use @Primary annotation to give higher preference to a bean when there are multiple beans of the same type.
For example:
@Component
@Primary
class Car implements Vehicle {}
 
@Component
class Bike implements Vehicle {}
 
@Component
class Driver {
    @Autowired
    Vehicle vehicle;
}
 
@Component
class Biker {
    @Autowired
    @Qualifier("bike")
    Vehicle vehicle;
}
Read more about this annotation on Spring - @Primary Annotation Example.

@Scope Annotation with Example

We use @Scope to define the scope of a @Component class or a @Bean definition. 
For example:
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON)
public class TwitterMessageService implements MessageService {
}

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class TwitterMessageService implements MessageService {
}
Read more about @Scope annotations on Spring @Scope annotation with Singleton Scope Example and Spring @Scope annotation with Prototype Scope Example.

@Profile Annotation with Example

If we want Spring to use a @Component class or a @Bean method only when a specific profile is active, we can mark it with @Profile.
We can configure the name of the profile with the value argument of the annotation:
@Component
@Profile("sportDay")
class Bike implements Vehicle {}
You can read more about profiles in this Spring Profiles.

@Import Annotation with Example

The @Import annotation indicates one or more @Configuration classes to import. 
For example: In a Java-based configuration, Spring provides the @Import annotation which allows for loading @Bean definitions from another configuration class.
@Configuration
public class ConfigA {

    @Bean
    public A a() {
        return new A();
    }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {

    @Bean
    public B b() {
        return new B();
    }
}
Now, rather than needing to specify both ConfigA class and ConfigB class when instantiating the context, only ConfigB needs to be supplied explicitly.
Read more about @Import annotation on Spring @Import Annotation.

@ImportResource Annotation

The @ImportResource annotation is used to load beans from an applicationContext.xml file into an ApplicationContext
For example: Consider we have applicationContext.xml spring bean configuration XML file on the classpath.
@Configuration
@ImportResource({"classpath*:applicationContext.xml"})
public class XmlConfiguration {
}
Read more about this annotation with a complete example on Spring @ImportResource Annotation.

@PropertySource Annotation

The @PropertySource annotation provides a convenient and declarative mechanism for adding a PropertySource to Spring’s Environment. To be used in conjunction with @Configuration classes.
For example: In this example, we are reading database configuration from file config.properties file and setting these property values to DataSourceConfig class using Environment.
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;

@Configuration
@PropertySource("classpath:config.properties")
public class ProperySourceDemo implements InitializingBean {

    @Autowired
    Environment env;

    @Override
    public void afterPropertiesSet() throws Exception {
        setDatabaseConfig();
    }

    private void setDatabaseConfig() {
        DataSourceConfig config = new DataSourceConfig();
        config.setDriver(env.getProperty("jdbc.driver"));
        config.setUrl(env.getProperty("jdbc.url"));
        config.setUsername(env.getProperty("jdbc.username"));
        config.setPassword(env.getProperty("jdbc.password"));
        System.out.println(config.toString());
    }
}
Read more about this annotation on Spring @PropertySource Annotation with Example.

@PropertySources Annotation

We can use this annotation to specify multiple @PropertySource configurations:
 @PropertySources({
  @PropertySource("classpath:config.properties"),
  @PropertySource("classpath:db.properties")
 })
 public class AppConfig {
  //...
 }
Read more about this annotation on Spring @PropertySources Annotation.
Learn complete Spring Core concepts on Spring Core Tutorial
Learn Spring framework 5 on Spring 5 Tutorial

Related Spring and Spring Boot Annotations

Comments