@Autowired和@Resource

作者:小脑斧
链接:https://www.zhihu.com/question/39356740/answer/2299259925
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

@Autowired

应用

有些使用不是很重要,知道有这样的用途就行。
官方地址:@Autowierd

(非重点)将 Autowired 应用于构造器上

在这里插入图片描述

As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean defines only one constructor to begin with. However, if several constructors are available and there is no primary/default constructor, at least one of the constructors must be annotated with @Autowired in order to instruct the container which one to use. See the discussion on constructor resolution for details.

(非重点)将 Autowired 应用于set方法

在这里插入图片描述

(非重点)将 Autowired 应用于常规方法

在这里插入图片描述

重点 将 Autowired 应用于字段上

在这里插入图片描述
重点:@Autowierd是根据类型装配,也就是autowireByType,所以一定要明确唯一类型。可以看底下的示例来理解

@Autowired required属性

可以通过该属性决定是否注入,可以从@Autowierd的源码实现中发现
在这里插入图片描述
在这里插入图片描述

剖析Autowired 实现

RootBeanDefinition

组件
AutowiredAnnotationBeanPostProcessor

AutowiredAnnotationBeanPostProcessor

Autowired 和@Resource的不同

Autowired 使用示例

@Autowierd实现依赖注入(接口),首先我们测试@Autowierd通过类型装配

@RestController
public class UserController {
    @Autowired
    private UserService userService;

    public void getName(){
        userService.getName();
    }
}

接口UserService

public interface UserService {
    void getName();
}

实现类一 UserServiceImpl1

@Service
public class UserServiceImpl1 implements UserService{
    @Override
    public void getName() {
        System.out.println("UserService1Impl");
    }
}


实现类二 UserServiceImpl2

@Service
public class UserServiceImpl2 implements UserService {
    @Override
    public void getName() {
        System.out.println("userServiceImpl2");
    }
}


Main启动类

@ComponentScan("org.example.mang")
public class AppConfig {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // 获取bean工厂BeanFactory获取UserController
        UserController userController = context.getBean(UserController.class);
        userController.getName();
    }
}
报错

在这里插入图片描述

报错原因

在我们的实例中@Autowierd标注的是接口,在之后会根据接口解析接口关联的实现类,在方法DefaultListableBeanFactory#doResolveDependency发现匹配的Bean大于1,于是决定先使用哪个,其实就是看

  • 哪个加了@Primary,我们的示例中都没有加,所以这里的autowierdBeanName为null
  • 哪个Priority更高,两个都没有实现,一样优先级
  • 极为特殊的场景,将Bean放入DefaultListableBeanFactory的resolvableDependencies中,可以直接从这里面拿
  • 根据名称匹配

这四个条件对于两个Service实现类来说处于同一竞争水平,所以两个都不会被选择,也就是说result为null。并且之后判断确认是不是想要注入集合Bean,我们这里当然也不是,只注入一个,所以抛异常

DefaultListableBeanFactory#doResolveDependency
在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值