Sping 依赖注入初探

60 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

作为一个初学者,对于Spring如何完成Bean管理以及如何完成Bean的装配一直都很好奇,今天初步的学习了一下,现在做个总结笔记。

1. 问题引出

Spring支持byName和byType两种形式进行Bean注册,随后可以利用ApplicationContext.getBean()的方法获取这个Bean实例。在使用xml显式配置和使用时还比较好理解。

但是当使用SpringBoot,一切都是使用注解来完成,一切也都好像没那么好理解了。

在SpringBoot中,我们使用注解来搞定一切,比如:@Component,@Service,@Controller等完成Bean的注册,再使用@Autowired或者@Resource来使SpringBoot完成自动装配和依赖注入。

那么,Spring是如何完成这一切的呢?

2. 反射

其实,SpringBoot完成这一切的过程基本上就是基于java中反射这个特性。

利用反射,我们可以知道java中的类一些特性,比如包含的属性、方法等。更好的是,我们可以利用反射机制,获取和注解相关的内容。

这样看来,在 1 中遇到的问题可以得到解释,可以想象Spring在进行初始化时,是利用了反射的机制,来判断当前的类、方法、对象使用了哪个注解,再根据注解的不同进行不同操作就可以了。

3. 依赖注入之给谁注入?

有下面这个例子:

@Component
public class OrderService {
}
@Component
public class UserService {
    @Autowired
    private OrderService orderService;
}

两个与业务相关服务,其中 UserService 依赖 OrderService。并且使用@Autowired完成了对于 orderService 的依赖注入。

根据2中对反射的介绍,不难想象,Spring一定是在某个地方使用了反射,来获取 UserService 中的属性,并且看一下这个属性是否具有@Autowired注解,来决定是否进行自动装配。

伪代码如下:

image.png

4.依赖注入之注入什么?

现在解决了给谁注入的问题,那么应该给它注入什么东西呢?

Spring中有一个大容器,里面管理着各种Bean,回答上面那个问题,用户需要什么,Spring就会注入什么到里面

@Component
public class UserService {
    @Autowired
    private OrderService orderService;
}

看上面的代码,现在想要注入一个跟 OrderService 有关的东西。

前文提到,Spring提供两种方式的注入:byName 和 byType,而@Autowired这个注解是采用的 byType 的方式完成依赖注入。

所以,要注入的是一个BeanType为 OrderService 的 Bean。

Spring在管理Bean的容器中去寻找 BeanType 为 OrderService 的东西。那么,这个容器的数据结构我们可以想象一下,哪种数据结构可以很快的做到 key-value 对应?

HashMap.所以可以知道在Spring中,使用了一个类似Map<String BeanType,Object BeanObj> 这样的一个结构来对Bean进行管理。

当通过byType的方式找到了Bean对象后,Spring会判断数量

  • 如果只有一个,那么肯定就是它;
  • 如果有多个,就再通过 byName 方式去找到唯一的那个Bean;

5.@Autowired 和 @Resource的区别

可以参考@Autowired 和 @Resource的区别, 不再赘述

参考文章: www.cnblogs.com/bhdyzxb/p/1…
www.cnblogs.com/nayitian/p/…
www.cnblogs.com/zanwanye/p/…
blog.csdn.net/qq_42764468…
m.php.cn/java/base/4…