Spring5学习总结

前言

为什么我们要使用Spring呢?如果答案只是停留在大家都在用,那么知识一定是停留在人云亦云阶段的。正因为我想开始更加深入的了解Spring并能更好的使用它,于是开启了源码学习的道路,并使用这篇文章记录我所学习的东西和一个思考的过程

正文

最前方写下Spring的官方文档,没有那篇文档写的比官网更详细了Spring 官网

为什么要使用Spring呢?

我现在所知道的原因一共有三个:

  1. 响应开闭原则:面向接口进行编程,不会把实现硬编码到代码中。
  2. 解决循环调用问题。
  3. 解决"模版"设计模式,使用重复代码的问题。

Spring 的主要思想 IOC/DI

把对象初始化以及实例化的主动权交给容器

Don't call me, I will call you. Spring会帮我们把对象初始化,实例化,并且把相关依赖也处理妥当。

举一个类似的例子,最近我也有在看"响应式编程"相关的思想,这宗思想也提倡的是不要总是惹人烦的轮询来问我,如果我准备好了一个,我会主动通知你的。两者有异曲同工之妙。

Spring 容器的流程

  1. 首先通过ClassPathResource读取Xml文件或者是配置好ComponentScan的配置文件,创建资源对象。
  2. 然后根据资源对象,创建IOC的Context容器
  3. 从容器中获取各种需要的bean进行使用。

通过Xml的方式一步一步进行配置,使得逻辑更加清晰,最外层的<beans> 为bean的集合,在开头需要写上验证方式,分别为 xsddtd,有兴趣可以自行百度。<bean> 指的就是一个对象,而依赖的对象使用<properties> 标签,这里需要注意的是依赖对象的属性,需要存在set方法才能注入成功,否则会报错。

Spring技术的KeyWord

  • BeanFatory: 管理Bean的生命周期,下面是官网的介绍:

    The BeanFactory API provides the underlying basis for Spring’s IoC functionality. Its specific contracts are mostly used in integration with other parts of Spring and related third-party frameworks, and its DefaultListableBeanFactoryimplementation is a key delegate within the higher-level GenericApplicationContext container.

  • Bean:

    • 如果对象被Spring进行管理,并且有相应的生命周期
    • 令一点比较重要的是bean 的实例化与添加依赖,使用的是反射以及内省机制。
    • Bean的查找一共有三种方式
      • 通过bean名称
      • 通过类的类型
      • 通过bean名称和类的类型
    • 关于Bean的官网介绍:

    A Spring IoC container manages one or more beans. These beans are created with the configuration metadata that you supply to the container (for example, in the form of XML <bean/> definitions).

    Within the container itself, these bean definitions are represented as BeanDefinition objects

  • ApplicationContext

    • 同样具有BeanFacotry,管理对象以及其相关依赖的功能,但是在应用中大多使用ApplicationContext,而不使用底层接口BeanFactory,因为ApplicationContext 功能更多,并且启动容器时帮我们管理所有的bean

Spring 基本配置

在原来没有出现注解的时候,我们都是使用xml进行配置,在一个xml中定义好命名空间,然后在下面设置一堆配置,其实还是很繁琐的。

要注意Bean元素起名字要使用id,而不能使用name,即使name可以使用多个别名,但是用处并不大。
当许多的配置都写进了同一个xml中会显得臃肿,所以可以将其拆分成多个文件,使用

<import resource="classpath:文件路径" />

到后来,我们可以使用JavaConfig的方式进行配置,代码开始变得小清新。
使用@Configuration代替原来整个xml的配置,然后在其中定义一个方法,配上@Bean注解,返回new 的对象,就相当于之前我们在xml 中的<bean>,bean中引用了别的bean只需要从方法参数传入即可。如果分离成了多个配置类使用@Import引入即可。

Spring Bean的创建

Bean的容器

BeanFactory在初始化Bean的时候,有延迟的特性,是一种懒加载,在从容器中取构造器的时候才会执行构造函数。

ApplicationContext在构建Spring容器的时候,就会立刻把管理的Bean进行初始化。但是Bean有一个参数(lazy-init)决定是否延迟初始化。

Bean的实例化方式
  1. 通过无参构造函数进行构建,使用的最多

  2. 静态工厂方式

  3. 实例工厂方法

    <bean id="" class="Factory的类"/>
    <bean id="" factory-bean="实例化Bean的名称" facotry-method="实例化方法"/>
    
  4. 实现FactoryBean实例化,实例工厂方法变种,与Mybatis结合使用较多。

    配置可以直接写为:

    <bean id="bean名称" class="实现了FactoryBean的工厂类名"/>
    

    Tips: 这里有个地方需要注意,我们因为规定了获得对象为getObject() 所以才不需要自己去指定实例化的方法。而且拿到的对象并不是工厂类对象而是通过FactoryBean拿到的。

Bean的作用域

Bean的对象相对于其他Bean的可见范围。

  1. singleton
  2. prototype
  3. request
  4. session
  5. websocket
  6. application
Bean 初始化以及销毁

在定义bean的时候只需要指定init-method方法,就相当于告诉spring在创建之后,进行初始化

同样的也存在destroy-method方法,注意: 这个销毁时候的方法被执行的前提是容器被关闭,如果时prototype的情况下,销毁方法是不会执行的,因为容器不知道我们会什么时候想要销毁它

Bean的生命周期
依赖注入的具体细节

在xml中可以使用以下代码注入(已经不推荐了):

<bean id="" class="" autowire="byName/byType/constructor/no"/>

注入方式:

  1. set方法注入

    在bean元素里加入以下即可注入:

    <property name="属性名称" value="属性的值" />

  2. 构造器注入

    在bean元素里加入以下即可注入:

    <constructor-arg type="构造器中的类型" name="构造器中的名字" value="构造器中的值" />

    type和name任选其一。

    Tips:如果一个bean只想在构造器里面使用可以把bean标签写在<constructor-args></constructor-arg>内部

注入值的类型:

  1. 常量类型 ,在xml中配置使用value字段
  2. 对象类型, 在xml中配置使用ref字段
  3. 引用类型,在xml中配置使用各自集合对应的元素:set,list...
元素的继承

当bean中的变量大多数相同,那么我们就可以像Java中抽取共同一样给提取出来提取的bean,但是其本质是xml配置的拷贝:

<bean id="base" abstract="true">

​ <property />

</bean>

然后在对应的需要base bean的地方

<bean id="bean1" parent="base">

</bean>

属性占位符

Property-placeholder, 在引入了 spring context之后,我们可以通过这个功能将变量提取出来,然后配置文件中读取变量,代码如下:

<context:property-placeholder location="classpath:配置文件的路径"/>

然后在bean中直接使用spel ${变量名}即可。

上面的代码通过注解的方式可以定义一个类,类上加入:

@PropertySource("classpath:配置文件的路径")

然后定义属性,在属性上加入@Value即可。

@Value(${属性名})
   private String xx;

使用注解实现DI

在前面的时候有说过,通过xml的方式,分为常量注入和引用注入。

那么在注解注入时,也有所体现:

引用注入:@Autowired,@Resource

常量注入:@Value

@Autowired
  1. 这个注解可以添加在属性上
  2. 可以添加在set方法上
  3. 也可以在set方法中注入多个属性值
  4. 还可以注入spring的内置对象 例如: BeanFactory, ApplicationContext

那么问题来了@Autowired是怎么帮助我们进行依赖注入的呢?

通过DI注解解析器

<context: annotation-config/>

寻找应用的方式:

1.首先通过注入的类型,使用setter方法或字段直接注入

2.如果找到了多个,则按照名字进行查找,如果没有匹配则报错

3.如果类型相同,名字不同,还可以通过@Qualifier("")定义具体注入的是哪个bean

@Resource

和Autowired作用是一样的, JAVAEE规范的注入注解.

但是寻找bean的顺序是不同的:

1.首先查找名字@Resource(name="bean 的名称")

2.如果有多个名字相同的,查找类型相同的

@Value

常量注入注解,加在变量上,为变量进行付值

使用注解实现IOC

IOC注解解析器,我们把需要组建进行了配置,也有引用这个注解的地方,但是还有一点很重要的就是IOC注解解析器:

<context: component-scan back-package="" />
@Component

被用来代替xml中配置bean的步骤

在@Component后,如果组建的功能更加具体,我们可以使用具体的注解

  • @Repository
  • @Service
  • @Controller
@Scope

用来指定对象的生命周期,最常用的就是singleton和prototype,默认为单例(singleton)的。

@PostConstruct

构建对象之后立刻执行,相当于之前使用bean xml定义的 init-method

@PreDestroy

在销毁对象之前执行,相当于之前我们在bean xml 定义的 destroy-method

Spring之AOP

可以参考我的另一篇文章传送门

Spring之Transaction

可以参考我的另一篇文章传送门

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容