Spring框架学习---Spring Framework上篇

前言:前短时间看了一下狂神的Spring部分的知识,感觉还是有点混乱,并且对于框架部分的学习,还是要靠自己去学习,这样既可以提高自己的自学的能力,还可以帮助自己对Spring有一个更深的记忆,下面主要是通过官方文档,和网上相关资料进行学习总结。

官网文档:Spring Framework中文版
狂神Spring Framework视频地址:【狂神说Java】Spring5最新完整教程IDEA版通俗易懂

一.依赖注入和控制反转

在这里插入图片描述
问题1:什么是依赖注入和控制反转

对象依赖:有A类,B类,在A类中B类以形参的方式作为A类中的某个方法的参数,这个时候我们就可以认为A类B类是相互依赖的,即A类依赖B类,当然在Java,C++中体现为:局部变量、方法/函数的参数或者是对静态方法的调用。

1.Java应用程序,通过各个对象协助组成,对象彼此之间相互依赖,这种方式缺乏将基本构建块组织成一个连贯的整体的方法(图1)。
在这里插入图片描述
相关学习链接:
Java语言中的关联与依赖关系
java对象间的关系(依赖,关联,组合,聚合)
Spring如何解决循环依赖问题

2.Spring 框架控制反转(IoC)组件通过提供一种形式化的方法来将不同的组件组成一个可以正常使用的应用程序,从而解决了这一问题(图2)。
在这里插入图片描述
在这里插入图片描述
3.Ioc也称为依赖注入(DI),这是一个过程,在此过程中,对象通过构造函数参数,工厂方法的参数或在对象实例从工厂方法构造或返回后设置的属性来定义其依赖关系即与它们一起使用的其他对象。然后,容器在创建Bean时注入那些依赖项。
在这里插入图片描述
回答上面的问题什么是控制反转和依赖注入:
下面的内容来源于:【第二章】 IoC 之 2.1 IoC基础 ——跟我学Spring3
4.控制反转

Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。

对于控制反转你需要搞懂以下三个问题:
4.1 谁控制谁

传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象,这时候就是程序控制对象
而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对象的创建,这时候就是Ioc容器控制对象

4.2 控制什么

主要控制了外部资源获取(不只是对象包括比如文件等)。

4.3 正转和反转:

正转:传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,对象主动接受依赖对象,也就是正转

反转:由容器来帮忙创建及注入依赖对象,对象被动的接受依赖对象,所以是反转

5.依赖注入

DI—Dependency Injection,即“依赖注入”:是组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。通过依赖注入机制,我们只需要通过简单的配置,而无需任何代码就可指定目标需要的资源,完成自身的业务逻辑,而不需要关心具体的资源来自何处,由谁实现。

对于依赖注入你需要搞懂以下四个问题:
5.1 谁依赖于谁

谁依赖于谁:当然是应用程序依赖于IoC容器;

5.2 为什么需要依赖

应用程序需要IoC容器来提供对象需要的外部资源;

5.3 谁注入谁

很明显是IoC容器注入应用程序某个对象,应用程序依赖的对象;

5.4 注入了什么

就是注入某个对象所需要的外部资源(包括对象、资源、常量数据)

最后对于控制反转和依赖注入我觉得狂神的理解方式挺不错的:
在这里插入图片描述
关于本部分的代码实例,你可以通过这篇博文进一步加深印象:Spring-IOC本质

二 Spring框架的模块

对于这部分本人觉得,你需要大致了解Spring框架包含哪一些组件,每一个组件的功能,相关技术。

在这里插入图片描述

2.1 Spring 框架

Spring 框架包含组织为约 20 个模块的功能。这些模块分为核心容器数据访问/集成WebAOP(面向方面的编程)检测消息传递测试,如下图所示。
在这里插入图片描述

2.2.1 核心容器

在这里插入图片描述

2.2.2 AOP 和检测

在这里插入图片描述

2.2.3 Messaging

在这里插入图片描述

2.2.4 数据访问/集成

在这里插入图片描述

2.2.5 Web

在这里插入图片描述

2.2.6 Test

在这里插入图片描述

三:核心技术

该部分对应官方文档III.核心技术部分
在这里插入图片描述

3.1 IOC容器

org.springframework.beansorg.springframework.context软件包是 Spring FrameworkIoC 容器的基础。BeanFactory提供了配置框架和基本功能,而ApplicationContext添加了更多企业特定的功能。BeanFactory接口提供了一种高级配置机制,能够 Management 任何类型的对象。 ApplicationContextBeanFactory的子接口。
Spring IoC容器Management 的对象称为* beans *。 Bean 是由 Spring IoC 容器实例化,组装和以其他方式 Management 的对象。
在这里插入图片描述

3.2 容器概述

接口org.springframework.context.ApplicationContext代表 Spring IoC 容器,并负责实例化,配置和组装上述 bean。容器通过读取配置元数据来获取有关要实例化,配置和组装哪些对象的指令。配置元数据以 XMLJava 注解Java 代码表示。
Spring 提供了ApplicationContext接口的几种实现方式。在独立应用程序中,通常创建ClassPathXmlApplicationContextFileSystemXmlApplicationContext的实例。
在这里插入图片描述通过上面的学习,大致的整体框架如图:
在这里插入图片描述
从上面的整个框架我们可以知道,要使用IOC容器就得先获取ApplicationContext接口,在独立应用程序中,通常创建ClassPathXmlApplicationContextFileSystemXmlApplicationContext的实例,实例的参数就是元数据(XMLJava 注解Java 代码),IOC容器通过对应的元数据来获取对应的beans(在beans中存放我们需要交给IOC容器管理的对象),进而来获取有关要实例化,配置和组装哪些对象的指令。

3.2.1 配置元数据

此配置元数据表示您作为应用程序开发人员如何告诉 Spring 容器实例化,配置和组装应用程序中的对象。
Spring 配置由容器必须 Management 的至少一个(通常是一个以上)bean 定义组成。基于 XML 的配置元数据显示了在顶级元素中配置为元素的这些 bean。 Java 配置通常在@Configuration类中使用@BeanComments 的方法。
在这里插入图片描述
以下示例显示了基于 XML 的配置元数据的基本结构:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

id属性是用于标识单个 bean 定义的字符串。 class属性定义 Bean 的类型,并使用完全限定的类名。 id 属性的值是指协作对象。在此示例中未显示用于引用协作对象的 XML。有关更多信息,请参见Dependencies

3.2.2 实例化容器

在这里插入图片描述
在这里插入图片描述
使用import可以导入多个元数据配置:
在resources中有二个xml的元数据配置,如果beans.xml要使用bean2.xml里的一个id名为hello2的bean
在这里插入图片描述
bean2.xml:
在这里插入图片描述

这时候只需要在beans.xml中通过import指向该bean2.xml即可
在这里插入图片描述
然后直接通过bean的id直接获取该bean即可:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.2.3 使用容器

ApplicationContext是高级工厂的界面,该工厂能够维护不同 bean 及其依赖关系的注册表。使用方法T getBean(String name, Class<T> requiredType),您可以检索 bean 的实例。
在这里插入图片描述
在这里插入图片描述

3.3 hellospring应用

下面通过创建一个hellospring的应用程序,程来感受整个过程。

  1. 该程序通过Maven获取相关jar包
  2. 元数据通过xml方式进行获取

在项目的pom.xml中导入springframework的jar包

     <dependencies>
       <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
           <version>5.3.9</version>
       </dependency>
   </dependencies>

1.程序框架:
在这里插入图片描述
2.Hello.class
在这里插入图片描述

3.beans.xml
在这里插入图片描述
4.HelloTest.class
在这里插入图片描述

运行HelloTest.class:
在这里插入图片描述
相关参数的解释:
beans.xml中的bean
beans中的bean,一个bean对应一个对象,这个对象就是我们交给IOC容器进行管理的对象。

   <bean id="hello" class="com.zhu.pojo.Hello">
       <property name="str" value="Spring"></property>
   </bean>
  1. id:对应bean的标识名,当要获取该bean的时候就是通过该标识名进行获取(我们通过IOC容器获取bean,IOC容器通过 getBean(String var1)方法进行获取,这里的var1指的就是该bean的标识名)
    在这里插入图片描述
  2. class:对应类的完整路径
    在这里插入图片描述
  3. <property name="str" value="Spring"></property>
    在这里插入图片描述
    在这里插入图片描述

相关的类解释:
1.ApplicationContext
接口org.springframework.context.ApplicationContext代表 Spring IoC 容器,并负责实例化,配置和组装上述 bean。
在这里插入图片描述

2.ClassPathXmlApplicationContext
ClassPathXmlApplicationContext 通过xml方式实例化ApplicationContext接口对象
在这里插入图片描述

3.FileSystemXmlApplicationContext
FileSystemXmlApplicationContext通过文件方式实例化ApplicationContext接口对象

总结:从上面的方式1和方式2我们会发现一个巨大的变化就是没有New对象,其实这就是IOC的作用,IOC通过依赖注入实现,项目中的beans.xml是配置信息,通过这一个配置信息,可以让IOC容器给我们自动分配一个对象,从而对象由spring来创建,管理,装配,这样我们只需要关心具体业务即可。

3.4 Bean 概述

这部分主要包括了对bean的概述,命名,实例化的一些基本的操作,相关的内容。

本节需要使用一个新的项目:
1.项目结构:
在这里插入图片描述
2.maven导包:

 <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
       <dependency>
           <groupId>org.springframework</groupId>
           <artifactId>spring-context</artifactId>
           <version>5.3.9</version>
       </dependency>
   </dependencies>

3.User
在这里插入图片描述

4.beans.xml

<bean id="user" class="com.zhu.pojo.User">
    <property name="name" value="张三"></property>
</bean>

在这里插入图片描述

5.测试类

 ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
        User user= (User) context.getBean("user");
        System.out.println(user.getName());

在这里插入图片描述
运行结果:
在这里插入图片描述

3.4.1 概述

在这里插入图片描述
在这里插入图片描述

3.4.2 命名 bean

在这里插入图片描述
在这里插入图片描述
1. <alias/>
在这里插入图片描述
在这里插入图片描述

2 . <name/>
<name/>等同于前面的别名不同的是name可以取多个
在这里插入图片描述
在这里插入图片描述

3.4.3 实例化 bean

在这里插入图片描述

3.4.3.1 有参构造函数

在前面的例子中,输出结果先是无参构造,然后再是user.getName()返回的结果,这个其实就是通过无参构造进行类初始化,再调用类的getName(),那有参构造进行类的初始化是怎么做的呢?
对于类的初始化使用<constructor-arg>进行初始化,初始化有以下几种:
1. 使用下标进行类初始化
这里的index值的就是构造函数的下标,注意下标从0开始

<!--    【1】使用下标进行类初始化-->
        <bean id="user" class="com.zhu.pojo.User">
         <constructor-arg index="0" value="李四"></constructor-arg>
        </bean>

在这里插入图片描述
运行结果:
在这里插入图片描述
分析一下,用new对象的方式来想想它是怎么执行的,下面对的所有操作的测试类均不变
在这里插入图片描述

1.实例化对象,这里通过有参构造进行实例化
在这里插入图片描述
对于这里的name,就是通过beans.xml配置文件进行赋值的
在这里插入图片描述
上面的操作和下面代码可以看作等价
在这里插入图片描述
2.使用类型进行类初始化

这里的type就是有参构造对应参数的数据类型
在这里插入图片描述
运行结果:
在这里插入图片描述
type里面对应的值就是这里name的数据类型
在这里插入图片描述
同样的上面的操作和下面代码可以看作等价
在这里插入图片描述

3. 使用参数名进行类初始化
在这里插入图片描述
在这里插入图片描述
运行结果:
在这里插入图片描述

3.4.3.2 构造函数加载问题

如果在beans.xml中创建二个不同对象,其中只调用一个对象的方法,另一个对象会被实例化吗?
在实体对象中创建一个UserT对象
在这里插入图片描述

然后在beans.xml中创建一个UserT的bean
在这里插入图片描述

测试类:
在这里插入图片描述

执行结果:
在这里插入图片描述
上面的操作说明,当beans.xml进行加载的时候,beans.xml的bean(对象)就已经被创建了。

3.4.2 Dependencies(依赖)

以前对象之间是依赖关系直接进行协作操作,而容器中的多个Bean是独立的,又是如何实现对象的协作?
在这里插入图片描述

3.4.2.1 依赖注入

基于构造函数的依赖项注入
在前面我们通过有参构造函数实例化,其实就是在进行依赖注入!

基于 Setter 的依赖项注入
常见的数据类型,如何进行依赖注入
在这里插入图片描述

  • 普通注入name=“参数” value=“初始化的值”。
  • ref=“address” 可以指向一个bean对象
    在这里插入图片描述
  • 数组,通过<array>表示数组,value表示数组的值
  • list集合,通过<list>表示集合,value表示集合的值
  • map,通过<map>表示map,<entry>表示一个键值对,key表示键,value表示值
  • set,通过<set>表示set,value表示值
  • null,通过</null>表示null
  • Properties通过<>

在这里插入图片描述
在这里插入图片描述
C命名和P命名空间注入(上面二种注入的快捷方式)
C命名是通过Set进行注入(相当于property),而P命名空间通过有参构造方法进行注入(相当于construct-args)
在这里插入图片描述
注意:C命名和P命名不能直接使用,需要导入XML约束

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

并且C和P还可以使用ref属性
例子:
在这里插入图片描述

3.4.3 Bean 作用域

在这里插入图片描述

  • 单例作用域(默认作用域,scope=“singleton”):创建的多个bean都共用一个对象

在这里插入图片描述
例子:
在这里插入图片描述

在这里插入图片描述

  • 原型作用域(scope=“prototype”):一个bean对应一个对象
    在这里插入图片描述
    例子:
    在这里插入图片描述

在这里插入图片描述

  • 其他作用域(Request ,Session Application等)对应Web中相应的作用域

3.4.4 自动装配

Cat.java
在这里插入图片描述

Dog.java
在这里插入图片描述
People.java
在这里插入图片描述
beans.xml配置文件代码
在这里插入图片描述
测试端代码:
在这里插入图片描述
运行效果:
在这里插入图片描述
在一个bean中引用另一个bean其实可以通过自动装配完成
在这里插入图片描述
在这里插入图片描述
再次运行:
在这里插入图片描述
如果把dog的id改了在运行:
在这里插入图片描述
在这里插入图片描述
这是因为byName通过判断id是否和X相等(setx,setCat=>x=cat,setDog,x=dog),(查找id)
在这里插入图片描述
将上面的autowire改成byType
在这里插入图片描述
再次运行:
在这里插入图片描述
这是因为byType会自动去容器上下文中查找,和自己对象属性类型相同的bean(查找class)
在这里插入图片描述

小结:
在这里插入图片描述
使用注解实现自动装配
在7.9这里(下文)提到了开发的时候可以使用Comments(注解)进行开发。
在这里插入图片描述
注解注入是在Xml之前执行的,所以如果同一个操作同时使用注解和Xml,Xml就会把注解的进行覆盖
在这里插入图片描述

注解开发的环境搭建(jdk1.5,spring2.5及以上支持注解开发)

  • 导入context约束和相关约束支持:
    context约束:
    xmlns:context="http://www.springframework.org/schema/context"
  • 开启注解
    <context:annotation-config/>

完整的开启注解代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

</beans>

@Autowired注解:(先通过使用byType找到相应属性,然后通过byName找相应属性)

  • @Autowired应用于构造函数
    在这里插入图片描述

  • @Autowired应用于“传统”设置方法
    在这里插入图片描述

  • @Autowired应用于具有任意名称和/或多个参数的方法
    在这里插入图片描述

  • @Autowired应用于字段,甚至将其与构造函数混合使用
    在这里插入图片描述

补充:Autowired(required=false),说明这个对象可以为null(属性使用@Nullable这个注解表示这个属性可以为null)
在这里插入图片描述

@Qualifier(value)可以指定唯一的bean对象进行注入
在这里插入图片描述
@Resource注解(先通过byName如果没有找到,再通过bytype),里面的name用来指定唯一的bean
在这里插入图片描述
小结(@Autowired()是先通过byType然后是byName,而@Resource()是先通过byName然后再是byName):
在这里插入图片描述

3.5 使用注解开发

  • <context:component-scan base-package="包名"> 用于扫描具体包中的注解

在这里插入图片描述

  • @Component组件,放在类上说明这个类被spring管理了,相当于前面的 <bean>

在这里插入图片描述
根据三层架构衍生了另外三个组件
在这里插入图片描述

  • @Value()对参数进行初始化,相当于 <property>
    在这里插入图片描述
  • @Configuration(),配置标签,表示这个类是一个配置类相当于bean.xml
    在这里插入图片描述

另一个配置类
在这里插入图片描述

pojo类
在这里插入图片描述

测试类中:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嘟嘟的程序员铲屎官

你的鼓励将是我最大的动力。

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值