SpringBoot学习笔记(一)

SpringBoot学习笔记(一)

暑期加入了沃天宇老师的实验室进行暑期的实习。在正式开始工作之前,师兄先让我了解一下技术栈,需要了解的有docker、k8s、springboot、springcloud。

谨以一系列博客记录一下自己学习的笔记。更多内容见Github

2021/7/12

因为我并非零基础,之前有用过SpringBoot进行过很简陋的项目开发,也仔细用过其它框架(ASP.NET),所以这次的学习过程主要是明确一些之前比较模糊的东西(包括Spring和SpringBoot),所以估计是一个一个小问题的实验探究。

资料

Spring官网:https://spring.io/

简单理解

spring整个框架最核心的就是IoC,在此基础上提供了AOP、MVC等能力。

而springboot的出现,是为了能够方便地构建和配置一个spring工程。

实验一 生命周期

需要探索的问题:

  1. 短生命周期的Bean可以被注入到长生命周期的对象中吗?
  2. 如果可以,会被重新注入吗?
  3. 如果不可以,有什么方法可以实现注入的效果呢?

实验方法

构造一个拥有默认的单例生命周期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后,并不会在收到请求的时候再次被注入。

如果想要实现每一次请求都会注入新的实例的效果,有两种方式:

  1. 在Controller的方法中加入参数,并且不要添加任何注解,或者添加@ModelAttribute,这样,这个参数就会从BeanFactory实例化,但是这种方法如果是Service层需要的话,就需要从Controller一层层传递下去,不太优雅;
  2. 使用方法注入(Method Inject),创建一个形如:<public|protected> [abstract] <return-type> theMethodName(no-arguments);的抽象方法,并将其注册为lookup方法(XML/注解均可),然后调用这个方法来手动创建实例。Spring会动态代理来创建这个抽象类的子类,这个子类会实现这个抽象方法:
@Lookup
protected abstract Req getReq();

参考:

上一篇:单例模式


下一篇:手撕设计模式【深度解析懒汉式单例】