As we know, Spring DI and Spring IOC are core concepts of the Spring Framework. Let’s explore some Spring core annotations from the org.springframework.beans.factory.annotationand org.springframework.context.annotation packages.
We often call these “Spring core annotations,” and we’ll review them in this article.
Here’s a list of all known Spring core annotations.
@Autowired
We can use the @Autowired
annotation to mark the dependency that Spring is going to resolve and inject. We can use this 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
-
@Bean
is a method-level annotation and a direct analog of the XML element. The annotation supports some of the attributes offered by, such as the init-method, destroy-method, auto-wiring, and name. - You can use the
@Bean
annotation in a@Configuration
-annotated or@Component
-annotated class.
The following is a simple example of an @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 { public CustomerService customerService() { return new CustomerService(); } public OrderService orderService() { return new OrderService(); } }
The preceding configuration is 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 the
@Bean
annotation in this article Spring @Bean Annotation with Example.
@Qualifier
This annotation helps fine-tune annotation-based auto-wiring. There may be scenarios when we create more than one bean of the same type and want to wire only one of them with a property. This can be controlled using the @Qualifier
annotation along with the @Autowired
annotation.
Example: Consider the EmailService
and SMSService
classes to implement the single MessageService
interface.
Create the MessageService
interface for multiple message service implementations.
public interface MessageService { public void sendMsg(String message); }
Next, 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 the @Qualifier
annotation.
public interface MessageProcessor { public void processMsg(String message); } public class MessageProcessorImpl implements MessageProcessor { private MessageService messageService; // setter based DI ("emailService") public void setMessageService(MessageService messageService) { this.messageService = messageService; } // constructor based DI public MessageProcessorImpl( ("emailService") MessageService messageService) { this.messageService = messageService; } public void processMsg(String message) { messageService.sendMsg(message); } }
Read more about this annotation in this article: Spring @Qualifier Annotation Example.
@Required
The @Required
annotation is a method-level annotation and 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 marks dependencies that we want to populate through XML:
setColor(String color) { this.color = color; } <bean class="com.javaguides.spring.Car"> <property name="color" value="green" /> </bean>void
Otherwise, the BeanInitializationException
will be thrown.
@Value
The 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 the @Value
annotation.
The Spring @Value
annotation also supports SpEL. Let’s look at some of the examples of using the @Value
annotation.
Examples: We can assign a default value to a class property using the @Value
annotation.
"Default DBConfiguration") private String defaultName;(
The @Value
annotation argument can be a string only, but Spring tries to convert it to the specified type. The following code will work fine and assign the boolean and integer values to the variable.
"true") private boolean defaultBoolean; @Value("10") private int defaultInt;(
This demonstrates the Spring @Value
— Spring Environment Property
"${APP_NAME_NOT_FOUND}") private String defaultAppName;(
Next, assign system variables using the @Value
annotation.
"${java.home}")
private String javaHome;
@Value("${HOME}")
private String homeDir;
Spring @Value
– SpEL
@Value("#{systemProperties['java.home']}")
private String javaHome;
(@DependsOn
The@DependsOn
annotation can force Spring IoC containers to initialize one or more beans before the bean, which is annotated by the @DependsOn
annotation.
The @DependsOn
annotation may be used on any class directly or indirectly annotated with the @Component
or on methods annotated with the @Bean.
Example: Let’s create FirstBean
and SecondBean
classes. In this example, the SecondBean
is initialized before bean FirstBean
.
public class FirstBean { private SecondBean secondBean; } public class SecondBean { public SecondBean() { System.out.println("SecondBean Initialized via Constuctor"); } }
Declare the above beans in Java based on the configuration class.
class AppConfig { ("firstBean") (value = { "secondBean" }) public FirstBean firstBean() { return new FirstBean(); } ("secondBean") public SecondBean secondBean() { return new SecondBean(); } }public
Read more about @DependsOn annotation on Spring – @DependsOn Annotation Example.
@Lazy
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 the @Component
or on methods annotated with the @Bean.
Example: Consider we have below two beans — FirstBean
and SecondBean
. In this example, we will explicitly load FirstBean
using the @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 on the configuration class.
class AppConfig { (value = true) public FirstBean firstBean() { return new FirstBean(); } public SecondBean secondBean() { return new SecondBean(); } }public
As we can see, bean secondBean
is initialized by the Spring container, while the bean firstBean
is initialized explicitly.
Read more about the
@Lazy
annotation with a complete example onSpring – @Lazy Annotation Example.
@Lookup
A method annotated with @Lookup
tells Spring to return an instance of the method’s return type when we invoke it.
Detailed information about this annotation can be found on Spring @LookUp Annotation.
@Primary
We use the @Primary
to give higher preference to a bean when there are multiple beans of the same type.
Car implements Vehicle {} @Component class Bike implements Vehicle {} @Component class Driver { Vehicle vehicle; } @Component class Biker { ("bike") Vehicle vehicle; }@Primary class
Read more about this annotation on Spring – @Primary Annotation Example.
@Scope
We use the@Scope
annotation to define the scope of a @Component
class or the @Bean definition. It can be either singleton, prototype, request, session, globalSession, or some custom scope.
For example:
value = ConfigurableBeanFactory.SCOPE_SINGLETON) public class TwitterMessageService implements MessageService { } @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) public class TwitterMessageService implements MessageService { }@Scope(
Read more about the @Scope annotations on Spring @Scope annotation with Singleton Scope Example and Spring @Scope annotation with Prototype Scope Example.
@Profile
If we want Spring to use the @Component
class or the @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:
"sportDay") class Bike implements Vehicle {}@Profile(
You can read more about profiles in this Spring Profiles.
@Import
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 the loading @Bean definitions from another configuration class.
class ConfigA { public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { public B b() { return new B(); } }public
Now, rather than needing to specify both the ConfigA class and ConfigB class when instantiating the context, only ConfigB needs to be supplied explicitly.
Read more about the @Import annotation on Spring @Import Annotation.
@ImportResource
Spring provides an @ImportResource
annotation used to load beans from an applicationContext.xml file into an ApplicationContext. For example: consider that we have applicationContext.xml Spring bean configuration XML file on the classpath.
"classpath*:applicationContext.xml"}) public class XmlConfiguration { }@ImportResource({
Read more about this annotation with a complete example onSpring @ImportResource Annotation.
@PropertySource
The @PropertySource
annotation provides a convenient and declarative mechanism for adding a PropertySource
to Spring’s Eenvironment to be used in conjunction with the @Configurationclasses.
For example, we are reading database configuration from the file config.propertiesfile and setting these property values to the DataSourceConfig class using the 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 { Environment env; 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
We can use this annotation to specify multiple @PropertySource
configurations:
"classpath:config.properties"), ("classpath:db.properties") }) public class AppConfig { //... }({ (
Read more about this annotation on Spring @PropertySources Annotation.
Hope you enjoyed this post on the best Spring annotations for your project! Happy coding!