SpringBoot学习笔记(一)
暑期加入了沃天宇老师的实验室进行暑期的实习。在正式开始工作之前,师兄先让我了解一下技术栈,需要了解的有docker、k8s、springboot、springcloud。
谨以一系列博客记录一下自己学习的笔记。更多内容见Github
2021/7/12
因为我并非零基础,之前有用过SpringBoot进行过很简陋的项目开发,也仔细用过其它框架(ASP.NET),所以这次的学习过程主要是明确一些之前比较模糊的东西(包括Spring和SpringBoot),所以估计是一个一个小问题的实验探究。
资料
Spring官网:https://spring.io/
简单理解
spring整个框架最核心的就是IoC,在此基础上提供了AOP、MVC等能力。
而springboot的出现,是为了能够方便地构建和配置一个spring工程。
实验一 生命周期
需要探索的问题:
- 短生命周期的Bean可以被注入到长生命周期的对象中吗?
- 如果可以,会被重新注入吗?
- 如果不可以,有什么方法可以实现注入的效果呢?
实验方法
构造一个拥有默认的单例生命周期Controller,往其中注入一个prototype
的Proto对象和一个request
生命周期的Req对象,如果没有报错,则说明短生命周期的Bean可以注入到长生命周期的对象中。
然后在Proto和Req对象的构造函数中,通过static
变量生成一个唯一的id,通过打印id来判断是否为同一个对象。
具体内容见:exp1
实验结果
测试结果如下:
Controller生命中周期 | 是否注入Proto | 是否注入Req | 能否成功启动 | 工作情况 |
---|---|---|---|---|
singleton | 是 | 是 | 否 | --- |
singleton | 是 | 否 | 能 | 所有请求都使用的同一个Req |
prototype | 是 | 是 | 能 | 每次请求都会重新创建这三个对象 |
request | 是 | 是 | 能 | 每次请求都会重新创建这三个对象 |
可见这似乎并不像ASP.NET
那样,IoC容器中有明确的生命周期长短singleton
>scoped
>transient
,短生命周期的对象无法注入到长生命周期对象中。而是使用了其它的体系。
总的来说,被依赖的对象的生命周期应当长于注入的对象,比如request
的对象在请求结束之后应当失效,但是singleton
却会长久地持有它。而prototype
的语义应当是每一次getBean
时都应当返回一个新的对象,并不在乎其持续多久。
所以说,一个prototype
被注入到singleton
后,并不会在收到请求的时候再次被注入。
如果想要实现每一次请求都会注入新的实例的效果,有两种方式:
- 在Controller的方法中加入参数,并且不要添加任何注解,或者添加
@ModelAttribute
,这样,这个参数就会从BeanFactory实例化,但是这种方法如果是Service层需要的话,就需要从Controller一层层传递下去,不太优雅; - 使用
方法注入
(Method Inject),创建一个形如:<public|protected> [abstract] <return-type> theMethodName(no-arguments);
的抽象方法,并将其注册为lookup
方法(XML/注解均可),然后调用这个方法来手动创建实例。Spring会动态代理来创建这个抽象类的子类,这个子类会实现这个抽象方法:
@Lookup
protected abstract Req getReq();
参考: