1. Introduction

Both the @Resource and @AutoWired annotations can be used for declarative dependency injection in Spring Framework applications. And these two notes often come up in interviews. Today we’ll sum them up.

2. @Resource

Full name javax.mail. The annotation. The Resource, it belongs to an annotation of JSR – 250 specification, included the Jakarta EE (J2EE). Spring provides support for this annotation. Let’s look at the rules for this annotation in detail.

This annotation is used on member properties and setter methods. By default@ResourceInjection by name, or by variable name or method parameter name if no name is explicitly declared.

If we wanted to represent polymorphism in the target Bean we could write:

/** ** * /** ** *@author felord.cn
 * @since 9 :26
 */
@Component
public class ResourceTest {
    @Resource
    private ApplicationRunner applicationRunner;    
    @Resource
    private ApplicationRunner runner;
    // ...
}
Copy the code

Qualifier constraints See Spring annotation @Qualifier for details

3. @Autowired

@autowired usually applies to constructors, member variables, and methods. It works like this:

This note is something we need to talk about, and it’s used quite frequently.

3.1 Annotation in the construction

You can inject the corresponding Bean by annotating the constructor of the target Bean.

package cn.felord;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

/ * * *@author felord.cn
 * @sinceHe * * /
@Component
public class AutowiredTest {
 private final ApplicationRunner applicationRunner;

    @Autowired
    public AutowiredTest(ApplicationRunner applicationRunner) {
        this.applicationRunner = applicationRunner; }}Copy the code

As of Spring Framework 4.3, @AutoWired annotations are no longer required to be added to the constructor if the target Bean defines only one constructor. If the target Bean has several constructors available and no primary/default constructor, at least one of them must be tagged @Autowired to indicate which constructor to use by the Spring IoC container.

3.2 Annotation on member variables

Like @Resource, @AutoWired can be tagged to a member variable of the target Bean.

/ * * *@author felord.cn
 * @sinceHe * * /
@Component
public class AutowiredTest {
    @Autowired
    private ApplicationRunner applicationRunner;
    
    // ...
    
}
Copy the code

3.3 Mark to method

Setter methods are used a lot in general. And an @autowired supports injecting multiple parameters.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {

    private ApplicationRunner applicationRunner;
    private EmployeeMapper employeeMapper;
    private DepartmentMapper departmentMapper;

    /**
     * Sets application runner.
     *
     * @param applicationRunner the application runner
     */
    @Autowired
    public void setApplicationRunner(ApplicationRunner applicationRunner) {
        this.applicationRunner = applicationRunner;
    }


    /** * Supports multiple parameters **@param employeeMapper   the employee mapper
     * @param departmentMapper the department mapper
     */
    @Autowired
    public void prepare(EmployeeMapper employeeMapper, DepartmentMapper departmentMapper) {
        this.employeeMapper = employeeMapper;
        this.departmentMapper = departmentMapper; }}Copy the code

You think this is the end? Here’s a way most people probably don’t care.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
    // Inject an array
    @Autowired
    private MovieCatalog[] movieCatalogs;
    
    private Map<String, Movie> movies;
    
    private Set<CustomerPreferenceDao> customerPreferenceDaos;
    
    / / into the set
    @Autowired
    public MovieRecommender(Set<CustomerPreferenceDao> customerPreferenceDaos) {
        this.customerPreferenceDaos = customerPreferenceDaos;
    }
            
    / / into the map
    @Autowired
    public void setMovieCatalogs(Map<String, Movie> movies) {
        this.movies = movies;
    }
   
    // ...
}
Copy the code

You can inject a Bean into an array or collection container of the target Bean. By default, autowiring will fail when no matching candidate Bean is available for a given injection point. There should be at least one matching element.

If you want the element in a particular Order, the Bean element can realize org. Springframework. Core. The Ordered interface or corresponding annotations @ @ Priority Order or standards. Based on some mechanisms, it is not recommended to use annotations for ordering. Otherwise, the expected results cannot be achieved. Interface Ordered is recommended.

3.4 Optional assembly

@Resource does not provide optional assembly and will throw an exception if it cannot be assembled; While @Autowired provides the required attribute (the default is true) to avoid this, set @Autowired to false.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
    // Initialize to null if no movieFinder is found without an exception
    @Autowired(required = false)
    private MovieFinder movieFinder;
    // ...
}
Copy the code

There are also operations here, and you can ignore the required attribute. Use Java 8’s java.util.Optional to indicate that the candidate Bean is Optional.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
public class SimpleMovieLister {
    // Use Optional to indicate that the candidate Bean is Optional
    @Autowired
    public void setMovieFinder(Optional<MovieFinder> movieFinder) {
     / /...}}Copy the code

Since Spring 5.0, you can also use the @ Nullable annotations, the annotations can you achieve detection logic or directly use the JSR – 305 provides javax.mail. The annotation. The Nullable.

/**
 * The type Autowired test.
 *
 * @author felord.cn
 * @since 9 :26
 */
@Component
public class AutowiredTest {
public class SimpleMovieLister {
    // Use the @nullable annotation to indicate that the candidate Bean is optional
    @Autowired
    public void setMovieFinder(@Nullable MovieFinder movieFinder) {
      / /...}}Copy the code

4. @Inject

As of Spring 3.0, Spring provides support for jSR-330 standard annotations (dependency injection). You need to introduce dependencies:

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>
Copy the code

Then you can use the relevant annotations for dependency injection, the main annotation is @javax.inject.Inject. In most cases this annotation can be used instead of @autoWired, but @Inject does not have a required attribute, but it can be used with java.util.Optional or @nullable to achieve the same effect.

For the most part, no one likes to introduce additional Jakarta EE dependencies to use an already existing feature, and Spring has choked off the Jakarta EE dependency injection ecosystem.

5. To summarize

@Resource and @Autowired have different priorities (see figure above). In addition, @resource belongs to the Jakarta EE specification and @Autowired belongs to the Spring category. @Resource cannot be used in construction parameters. @autowired supports the required attribute. From an object-oriented perspective, @Resource is more suitable for fine-grained injection of polymorphism, while @AutoWired is more focused on singleton injection of polymorphism. Inject @inject doesn’t need to be discussed too much, just as an add-in. Well today is over here, a lot of attention: code farmers xiao Pangge, more dry goods knowledge to share.

Follow our public id: Felordcn for more information

Personal blog: https://felord.cn