Location>code7788 >text

Talk about the difference between @Autowired and @Resource

Popularity:841 ℃/2025-04-28 09:30:41

1. Preface

Have worked in many companies, seen many projects, found@Autowiredand@ResourceThe use is the same mess.

Used in a project@AutowiredYes, useful@Resourceof,

Some classes are even used in a while@Autowired, use it in a while@Resource, although it does not affect the implementation of business functions, it looks really messy.

This blog mainly explains the differences between these two annotations.

2. Different sources

@AutowiredIt is annotation of the Spring framework.

@Resourceis annotation for Java (from JSR-250) and is supported compatible with the Spring framework.

Note: JSR is the abbreviation of Java Specification Requests, which means Java specification proposal.

3. Different dependency search order

@AutowiredFirst look up by type, if there are multiple beans, then look up by name.

@ResourceFirst look up by name, and if it cannot be found, then look up by type.

3.1 Verify @Autowired first search by type, then search by name

First, create a new interface:

public interface NotificationService {
    void send();
}

Then create the first implementation class:

import ;

 @Service
 public class EmailService implements NotificationService {
     @Override
     public void send() {
         ("Send email notification");
     }
 }

Then create a second implementation class:

import ;

 @Service
 public class SmsService implements NotificationService {
     @Override
     public void send() {
         ("Send SMS Notification");
     }
 }

Finally, create a new controller and use it@AutowiredTo inject NotificationService:

import ;
import ;

@RestController("/dependency/injection/test")
public class NotificationController {
    @Autowired
    private NotificationService notificationService;
}

Start the project at this time and will be thrownabnormal,

The reason is that there are 2 Beans of NotificationService type, Spring is not sure which one to inject, which also proves that@AutowiredThe default is to search by type first.

There are three solutions to solve this problem.

The first solution is to use@Primaryannotation:

import ;
 import ;

 @Service
 @Primary
 public class EmailService implements NotificationService {
     @Override
     public void send() {
         ("Send email notification");
     }
 }

Note: If there are multiple beans of the same type, Spring will be preferred@PrimaryAnnotation marker bean.

The second solution is to modify the field name:

@Autowired
private NotificationService emailService;

The third solution is to use@Qualifierannotation:

@Autowired
@Qualifier("emailService")
private NotificationService notificationService;

Proof of the second and third solutions@AutowiredIt is searched by name.

The difference between the two is that the second solution is to look up by field name (implicitly), and the third solution is to look up by specified name (explicitly).

3.2 Verify @Resource first search by name, then search by type

First, create a new interface:

public interface NotificationService {
    void send();
}

Then create the first class (Note: Not an implementation class):

import ;

 @Service
 public class EmailService {
     public void send() {
         ("Send email notification");
     }
 }

Then create a second class (Note: It is the implementation class):

import ;

 @Service
 public class SmsService implements NotificationService {
     @Override
     public void send() {
         ("Send SMS Notification");
     }
 }

Finally, create a new controller and use it@ResourceTo inject NotificationService:

import ;

import ;

@RestController("/dependency/injection/test")
public class NotificationController {
    @Resource
    private NotificationService emailService;
}

Start the project at this time and will be thrownabnormal,

The reason is that the EmailService Bean found by field name is not the NotificationService type, which also proves that@ResourceThe default is to search by name first.

There are two solutions to solve this problem,

The first solution is to explicitly specify the Bean name:

@Resource(name = "smsService")
private NotificationService emailService;

The second solution is to modify the field name:

@Resource
private NotificationService notificationService;

The second solution can be injected successfully, which also proves that@ResourceIt is searched by type.

At this time, because NotificationService only has one implementation class SmsService, the direct injection is successful.

If you change the EmailService to the NotificationService implementation class:

import ;

 @Service
 public class EmailService implements NotificationService {
     @Override
     public void send() {
         ("Send email notification");
     }
 }

Then the project will be thrownabnormal.

4. Different parameters

@AutowiredThere is only 1 required parameter.@ResourceThere are 7 parameters such as name and type.

4.1 @Autowired parameters

@AutowiredThere is only 1 parameter, as shown below:

public @interface Autowired {
    boolean required() default true;
}

By default,@AutowiredThe requirement dependency must exist, and can be passedrequired = falseSet to optional.

@Autowired(required = false)
private NotificationService notificationService;

4.2 @Resource parameters

@ResourceThere are 7 parameters as follows:

public @interface Resource {
    String name() default "";

    String lookup() default "";

    Class<?> type() default ;

    enum AuthenticationType {
            CONTAINER,
            APPLICATION
    }

    AuthenticationType authenticationType() default ;

    boolean shareable() default true;

    String mappedName() default "";

    String description() default "";
}

By default,@ResourceFirst look up the bean based on the field name. You can explicitly specify the name through the name parameter and explicitly specify the type through the type parameter.

@Resource(name = "emailService", type = )
private NotificationService notificationService;

5. The supported dependency injection methods are different

@AutowiredSupports field injection, Setter method injection and constructor injection.

@ResourceSupports field injection and Setter method injection, and does not support constructor injection.

5.1 @Autowired support for dependency injection

1) Field injection:

@RestController("/dependency/injection/test")
public class NotificationController {
    @Autowired
    private NotificationService notificationService;
}

This method is not recommended, but is used the most in actual projects.

2) Setter method injection:

@RestController("/dependency/injection/test")
public class NotificationController {
    private NotificationService notificationService;

    @Autowired
    private void setNotificationService(NotificationService notificationService) {
         = notificationService;
    }
}

3) Constructor injection

@RestController("/dependency/injection/test")
public class NotificationController {
    private final NotificationService notificationService;

    public NotificationController(NotificationService notificationService) {
         = notificationService;
    }
}

This method is the preferred method officially recommended by Spring.

5.2 @Resource-supported dependency injection method

1) Field injection:

@RestController("/dependency/injection/test")
public class NotificationController {
	@Resource
    private NotificationService notificationService;
}

2) Setter method injection:

@RestController("/dependency/injection/test")
public class NotificationController {
    private NotificationService notificationService;

	@Resource
    private void setNotificationService(NotificationService notificationService) {
         = notificationService;
    }
}

@ResourceConstructor injection is not supported, if used on the constructor@ResourceAnnotation, IDEA will prompt:

'@Resource' not applicable to constructor。

6. Summary

@Autowiredand@ResourceThey are all annotations used to implement dependency injection, but there are differences between the two, mainly the following 4 points:

  1. Different sources

    @AutowiredIt is annotation of the Spring framework.

    @Resourceis annotation for Java (from JSR-250) and is supported compatible with the Spring framework.

  2. Different order of dependency search

    @AutowiredFirst look up by type, if there are multiple beans, then look up by name.

    @ResourceFirst look up by name, and if it cannot be found, then look up by type.

  3. Different parameters

    @AutowiredThere is only 1 required parameter.@ResourceThere are 7 parameters such as name and type.

  4. The supported dependency injection methods are different

    @AutowiredSupports field injection, Setter method injection and constructor injection.

    @ResourceSupports field injection and Setter method injection, and does not support constructor injection.

The article continues to be updated, welcome to follow the WeChat public account "Shencheng Strange People" to read it as soon as possible!