注解@autowired与@resource的区别

注解@autowired与@resources的区别

@Resource和@Autowired都是用于bean的依赖注入,其实@Resource并不是Spring的注解,它是J2EE的,它的包是javax.annotation.Resource,而@Autowired的包是org.springframework.beans.factory.annotation.Autowired,但Spring支持该@resources的注入(Spring支持几个JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct、@PreDestroy)。

1、@autowired源码

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
    boolean required() default true;
}

2、@resources源码


package javax.annotation;

import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;

@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {

    String name() default "";

    String lookup() default "";

    Class<?> type() default java.lang.Object.class;

    enum AuthenticationType {
            CONTAINER,
            APPLICATION
    }

    AuthenticationType authenticationType() default AuthenticationType.CONTAINER;

    boolean shareable() default true;

    String mappedName() default "";

    /**
     * Description of this resource.  The description is expected
     * to be in the default language of the system on which the
     * application is deployed.  The description can be presented
     * to the Deployer to help in choosing the correct resource.
     */
    String description() default "";
}

3、共同点
都可以标注在字段和setter方法上。当然,如果标注在字段上,则不需要再写Setter方法。

4、不同点
(1)@autowired只按照byType注入。默认情况下要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false。如:@Autowired(required=false),如果我们想使用byName注入,可以结合@Qualifier注解进行使用,如下:

@Autowired(required=false)
@Qualifier("userService")
private SserService userService;

problem:从源码上看@autowired是根据type进行依赖注入,但是当把其所依赖的类命名后,哪怕同一个接口存在多个实现类,也不会导致依赖冲突,这里究竟如何实现的?

(2)@Resource默认按照byName自动注入,有两个重要属性:name和type。Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用那么属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略,如果既不指定name也不指定type属性,这是将通过反射机制使用byName自动注入。

@RestController
public class UserController {

    @Autowired
    private UserMapper userMapper;


    @Resource
    //@Rsource(name = "userService")
    private UserService userService;

    @Resource(name="userService",type=userService.class)
    public void setUserService(UserService userService) { // 用于属性的setter方法上
        this.userService = userService;
    }
}

@Resource装配规则:
1、如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
2、如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
3、如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或找到多个,都会抛出异常。
4、如果既没有指定name,也没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个byType进行匹配,如果匹配则自动装配。通过设置CommonAnnotationBeanPostProcessor 的‘fallbackToDefaultTypeMatch’属性为“false”(默认值是“true”)可以禁用这一特性。

猜你喜欢

转载自blog.csdn.net/m0_37179470/article/details/81144662