• @AutoWired与@Resource注解


    首先对于这俩个注解:

    自动绑定(Autowiring)模式:

    模式

    说明

    no

    默认值,未激活 Autowiring,需要手动执行依赖注入对象

    byName

    根据被注入属性的名称作为Bean名称进行依赖查找,并将对象设置到该属性

    byType

    根据被注入属性的类型作为依赖类型进行查找,并将对象设置到该属性

    constructor

    特殊的byType类型,用户构造器参数

    @Autowired是Spring中的注解,他是通过byType模式去查找注入bean

    package org.springframework.beans.factory.annotation;
    
    import java.lang.annotation.Documented;
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Autowired {
        boolean required() default true;
    }

    @Resource是JSR-250中提供的注解,即Java提供的注解,从包名就可以看出来,他是通过byName模式去查找bean

    Autowired:org.springframework.beans.factory.annotation.Autowired Resource:javax.annotation.Resource

    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 "";
    
        String description() default "";
    }

    @AutoWired

    @Autowired的依赖注入过程是由AutowiredAnnotationBeanPostProcessor支持的

    具体的注入逻辑在DefaultListableBeanFactory#doResolveDependency方法

    @Autowired的注入逻辑如下

    1. 找到所有类型符合的bean
    2. 如果没有类型符合的bean,则看@Autowired的required属性是否为true,是则抛出异常,否则返回null
    3. 如果只有一个,则将这个bean注入
    4. 如果有多个bean 4.1 选择其中带有Primary注解的bean,如果只有一个直接注入,如果有多个bean带有Primary注解则报错,如果不存在就下一步 4.2 选择其中优先级最高的bean(优先级使用javax.annotation.Priority表明),如果只有一个直接注入,如果有多个bean的优先级并列最高则报错,如果不存在就下一步 4.3 选择beanName和当前要注入的属性名相同的bean进行注入,有则注入,没有则报错

    例:

      @Autowired
        private DictionaryService dictionaryService;

    如上代码所示,这样装配回去spring容器中找到类型为DictionaryService 的类,然后将其注入进来。这样会产生一个问题,当一个类型有多个bean值的时候,会造成无法选择具体注入哪一个的情况,这个时候我们需要配合着@Qualifier使用。即为:ByType改为ByName,或者使用byType导入带有@Primary注解的bean

    //byType改为ByName
    @Autowired @Qualifier(name
    ="dictionaryServiceImpl") private DictionaryService dictionaryService;

    //配合bean带有@primary注解导入
    @Autowired
        private DictionaryService dictionaryService;

    如果没有找到bean,有俩种处理方式required设置,需要抛异常设置为reqiured为true

    @Autowired(required=ture)
        private DictionaryService dictionaryService;

    @Resource

    @Resource的依赖注入过程是由CommonAnnotationBeanPostProcessor支持的

    具体的注入逻辑在CommonAnnotationBeanPostProcessor#autowireResource

    @Resource的注入逻辑如下

    1. 如果@Resource指定了name,则只会按照name进行查找,当找不到时抛出异常,找到将bean注入
    2. 如果@Resource没有指定name,则把属性名作为名字进行查找,找到将bean注入,当按照名字查找不到时,按照类型进行查找

    「注意:@Resource按照类型查找的逻辑和@Autowired的一样,因为都是调用了DefaultListableBeanFactory#doResolveDependency方法」

    例:。 

    @Resource
    private OutstockService outstockService;

    @Resource(name="outstockServiceImpl ") 

    private OutstockService outstockService;

    @Resource(type="OutstockService ")
    private OutstockService outstockService;
    @Resource(name="outstockServiceImpl",type="OutstockService")
    private OutstockService outstockService;

    ①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

    ②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

    ③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

    ④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配

    总结

    @Autowired:先byType再byName

    @Resource:先byName再byType(当指定@Resource name属性时,只会byName)

  • 相关阅读:
    GridSearchCV.grid_scores_和mean_validation_score报错
    scikit-learn使用fetch_mldata无法下载MNIST数据集的问题
    Python数据科学手册Seaborn马拉松可视化里时分秒转化为秒数的问题
    Jupyter导出PDF从入门到绝望(已解决)
    食谱数据库数据找不到的问题
    TensorBoard计算加速
    TensorBoard可视化
    TensorFlow高层封装:从入门到喷这本书
    <!DOCTYPE html> 详解
    不同数据库之间表数据的迁移
  • 原文地址:https://www.cnblogs.com/lqh969696/p/15964323.html
Copyright © 2020-2023  润新知