February 18, 2022

Spring @Resource Annotation

For autowiring in Spring apart from using @Autowired annotation there is also support for JSR 330’s @Inject annotation and JSR-250 @Resource annotation. In this post we'll see how to use Spring @Resource annotation for autowiring.

@Resource annotation in Spring

@Resource annotation can be used on fields or bean property setter methods. @Resource takes a name attribute. By default Spring interprets that value as the bean name to be injected. In other words, this annotation follows autowire=by-name semantics. For example-

@Service
public class OrderService {
  private IStore store;
  // Autowired on Setter
  @Resource(name="retailStoreBean")
  public void setStore(IStore store) {
    this.store = store;
  }
  public void buyItems() {
    store.doPurchase();
  }
}

Spring will look for a bean named “retailStoreBean” to inject here in the store property.

The name specified with @Resource annotation is optional. If no name is explicitly specified, the default name is derived from the field name or setter method.

In case of a field, it takes the field name. In case of a setter method, it takes the bean property name.

If @Resource annotation doesn't find the bean with the same name it will try to match using type. So there is also automatic switching to autowire=byType in case autowiring by-name is not fulfilled.

Spring @Resource annotation Example

In the example there is a class to place order called OrderService and purchase can be done from a Store. In OrderService class dependency for store has to be autowired for which @Resource annotation is used.

javax.annotation.Resource is part of javax.annotation API so you may need to add that dependency in order to work with @Resource annotation.

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>
OrderService.java
import javax.annotation.Resource;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
  private IStore store;
  // Autowired on Setter
  @Resource(name="retailStoreBean")
  public void setStore(IStore store) {
    this.store = store;
  }
  public void buyItems() {
    store.doPurchase();
  }
}

Here name attribute has the value “retailStoreBean” that means there should be a bean with this name that has to be injected to the store property.

Istore interface
public interface IStore {
  public void doPurchase();
}
RetailStore.java
@Component("retailStoreBean")
public class RetailStore implements IStore {
  public void doPurchase() {
    System.out.println("Doing purchase from Retail Store");
  }
}

Name of the bean is given as “retailStoreBean” which is the name this bean get registered with the container.

XML Configuration
<?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="com.knpcode" />

</beans>
Class to run the example
public class App {
  public static void main(String[] args) {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("appcontext.xml");
    OrderService orderService = context.getBean("orderService", OrderService.class);
    orderService.buyItems();
  }
}
Output
Doing purchase from Retail Store

If name is removed, the code till works as @Resource switches to byType autowiring.

@Resource
public void setStore(IStore store) {
  this.store = store;
}

That's all for the topic Spring @Resource Annotation. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment