内容简介:本篇是《跟我猜Spring-Boot》系列的第2篇(Oh,我竟然已经写了10篇了,真不容易)。在上一篇中,我们实现了我们之前已经在工程中定义了
引&目标
本篇是《跟我猜Spring-Boot》系列的第2篇(Oh,我竟然已经写了10篇了,真不容易)。
在上一篇中,我们实现了 Bean 的创建,但是仅仅是创建而已,并没有真正的实现Bean的注入。那么在今天这篇中,我们要去实现bean的自动注入。
我们之前已经在工程中定义了 SimpleService
和 SimpleController
这两个类,那么这篇文章,我们要把 SimpleService
自动注入到 SimpleController
中;
SimpleController.java
因为目前只是一个控制台程序,没办法进行真正的调用和展示,所以我给 SimpleService
加一个输出,用来表示这个类的的唯一性。这样, SimpleService
就变成了这样:
SimpleService.java
现在虽然有了调用,但是还是没有办法去验证我们的想法。
干脆,将计就计,我们再加上一个 PostContruct
的注解吧 :)
SimpleController.java
依赖注入的需求分析
由我们目标程序的更改,可以看出我们这次对 mini-boot
的更改主要在如下几点:
-
定义
PostConstruct
和Autowired
-
以
Autowired
为标记,实现依赖注入 -
以
PostContruct
为标记,实现Bean在创建的自动初始化
以3条是我们这次要实现的直观目标,然而,由于我们之间 过于简单 的设计,我们有一个问题要解决,即:
我们需要有地方可以存储,查找已经已经生的bean !
那么这个问题显然要比1,2,3条更重要一些,于是
前文挖坑,后文填坑
我们的目标变成了:
-
实现Bean的存储和管理
-
定义
PostConstruct
和Autowired
-
以
Autowired
为标记,实现依赖注入 -
以
PostContruct
为标记,实现Bean在创建的自动初始化
Step 0 Bean的存储和管理
在Spring中,从外部得到一个bean 方式下:
-
通过依赖注入或其他方式得到
ApplicationContext
-
通过
ApplicationContext.getBean
来得到相应的bean.
通过这两条,显而易见:
-
我们也照般一个
ApplicationContext
-
而通过类名或类拿到bean这种逻辑,显然是一个map.这样,我们的
ApplicationContext
变得很好实现:
ApplicationContext.java
嗯,有了 ApplicationContext
之后,我们就可以在生成bean的同时用一个applicationContext把所有的bean都保存起来。这时,我们的 Application.loadBeans
的函数有了一点点变化:
Application.loadBeans
可以看到,这时的变化还很小,我们只是在开始初始化了一个context ,然后在bean生成后,将bean保存在context中
OK,保存bean的功能完成了(只是把前人的坑填了而已),下一步要开始我们正式的工作了。
Step1 定义Annotation
之前已经分析了,我们需要定义 Autowired
和 PostContruct
两个注解,都简单的很,做一下声明即可:
Autowired.java
PostConstruct.java
同样注意,我们在这里要加入 @Retention(RetentionPolicy.RUNTIME)
这一行,具体的功能和区别,咱会找机会详解(又在挖坑,不挖不舒服基)
Step2 以@Autowired为标记,实现依赖注入
嗯,我们要进行最激动人心的部分了,实现依赖注入,即我们要将 SimpleService
自动 注入 到 SimpleController
中。
But ....
一切已经非常水到渠成了,又双叒叕有什么好激动的?我们要做的无非就是:
-
把所有的bean从context里取出来;
-
用反射得到bean的每一个字段;
-
检查这个字段有没有加autowird注解;
-
如果有,检查这个字段类型是不是一个bean;
-
如果是,取出来用反射进行赋值;
因为我们用的是Map进行的存储,所以4,5两步可以合并为:
4-5. 按这个字段类型取到bean,如果不为空,就赋值。
因为想的清楚,代码自然一气呵成,即在 Application.loadBeans
后面增加这个注入的逻辑:
Application.loadBeans
同时,我们为ApplicationContext加了一个新的方法,用来得到所有的bean
ApplicationContext.java
注意这里面有一个点,即Applicaton.loadBeans我们循环了两次:
-
第一次是生成bean并存储
-
第二次是将所有的bean取出来,用依赖注入的形式为每个bean进行赋值
这样做的原因也很明显:
为了保证在注入时可以拿到我们想要的bean,必须在所有的bean都生成后进行处理
Step3 以@PostConstruct为标记,实现初始化方法的自动运行
到上一步,我们的依赖注入实际上已经完成了,但是由于目前我们 mini-boot
这个框架太简单了,根本没办法验证我们成功与否。
所以,我们在这里顺带将@PostContruct的机制也实现一下,即类加载后的自动初始化。
有了上一步的工作,你会发现,我们这次的工作变得非常程式化和无味了,即:
-
把所有的bean从context里取出来;
-
用反射得到bean的每一个 方法 ;
-
检查这个 方法 有没有加 PostContruct 注解;
-
如果有, 使用反射执行这个方法 ;
你一定会注意到,这里我有一些字体是标粗的,标粗的原因是因为:这里的1-4是 我从上面复制下来的,标粗的只是更改的部分 。
即然实现思路都能复制,那么代码也变得很容易了。
Application.loadBeans
OK ,现在编译工程,执行,你会看到如下输出:
这个输出中:
-
第一行是controller自动创建
-
第二行表时service自动创建,并且唯一id 是 xxxx
-
第三行是我们的controller 中init函数的输出,可以看到 这里service 已经不为空了,并且就是我们之间自动创建的那个!
也就是说:
-
我们已经按照预期实现了简单的自动注入
-
我们同时按照预期实现了简单的自动运行初始化函数
现在,静静的回想一下我们此文的内容,是否有某扇大门,已经向您敞开
其他
不给源码的分享都是耍流氓!
所以,我们的项目地址是:https://github.com/yfge/mini-boot 由于,随着文章的发布,本代码会不停的更新,所以,本章的tag是 : article-02
(原谅我起名字的水平)
关于老拐瘦
-
散养程序猿,野生架构狮
-
二流搬砖工,三流摄影师
-
假正经真逗比,装文艺实二逼
所以,这么一个公众号里,会有代码,有段子,有美图,有鸡汤,反正,乱七八遭的,没准碰上哪个刚好就烦到您了呢
啥也不说,扫码关注吧
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 跟我猜 Spring Boot:bean 的注入
- 我猜你需要这个Python调试工具
- iOS 小游戏项目——你话我猜升级版
- 跟我猜 spring-boot: bean 的创建
- 跟我猜 spring-boot: bean 的创建
- 跟我猜 Spring Boot:第一次优化 (bean 的加载)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Google's PageRank and Beyond
Amy N. Langville、Carl D. Meyer / Princeton University Press / 2006-7-23 / USD 57.50
Why doesn't your home page appear on the first page of search results, even when you query your own name? How do other web pages always appear at the top? What creates these powerful rankings? And how......一起来看看 《Google's PageRank and Beyond》 这本书的介绍吧!