杨博超-spring教程-day01-笔记

文章目录

2019年6月11日

https://www.youtube.com/watch?v=8e1v8QlHNyQ&t=451s

01-框架简介

image-20210925172404325

什么是框架

没有标准答案,面试时候,你不要官方回答,你要理解了。你官方回答,里面会有特殊的词汇。

面试官也听不懂,这问题就接踵而来了。

比如说什么是对象,万物皆对象。十年前这么说可以,现在这么说,你完蛋了。

什么是万物皆对象。

面试时候回答问题,一定要有总结性,要有自己的理解。

框架,就是框和架,框就是有一定的约束性,架就是有一定的支撑性。

什么是框架,就是具有约束性地去支撑我们实现某些功能的半成品的项目。

  • 约束性
    • 框架当中都有一套标准。
    • 咱们之前写jdbc+serlet+jsp的时候,每个人写的方式都不一样。
    • 框架当中基本会将所有的模式定义好。
    • 可以为开发的过程当中,定义一些标准。
    • 你就不能随便写了。
  • 支撑性
    • 它为什么能够支撑我们实现各种功能。
    • 那是因为spring的底层就是对java当中各种功能的封装。
    • 为啥mybatis能够对持久化访问。
    • jdbc的时候就叫做java database。
    • mybatis就是封装了jdbc。
    • spring的时候也是这样。为什么这个框架能够实现这个功能。
    • 原来我是用jsp+servlet+jdbc就能够实现了。框架就是对这些的封装。
    • 支撑性就是有一个基础的,就是能够封装java当中的各种技术。
  • 半成品
    • 拿着一个框架,不能够当成一个完整的项目去使用。
    • 框架叫做半成品的项目是因为里面封装的各种技术都有,但是里面缺少业务逻辑。
    • 框架加上业务逻辑,就是一个完整的项目了。

框架的简单的历史

没啥意思。

SSM = spring + springmvc + mybatis

structs1

stucts2

hibernate

spring

springmvc

mybatis

  1. structs1:MVC框架controller-model-view
    1. 出现最早的mvc框架。
    2. structs1封装的就是servlet。
    3. 我们用structs1就可以完成相当于对servlet的操作。
    4. 各个程序员把structs1当成是至宝,之前要用jsp+servlet,用structs1很简单。
    5. 封装产生的,最直接的效果,就是减少代码量。
    6. structs1当中有很多bug和漏洞的。
    7. 完全被淘汰。
  2. stucts2:MVC框架controller-model-view
    1. structs2开发出来的时候,基本上没有人用。
    2. structs1好用了,为啥要用structs2。
    3. 原来structs2不叫这个名字,没人用之后,就改了名字,碰瓷structs1
    4. structs2封装的是过滤器,封装的是filter,比structs1好用。
    5. 很少很少有人用。
  3. hibernate:持久层框架
    1. 这个东西非常神奇。
    2. 用hibernate,表都不需要建。
    3. 创建web项目当中有个web.xml。
    4. 在hibernate当中只需要配置文件创建好,关系配置好了之后,表都自动给你建了。
    5. hibernate当中不需要写sql语句,一个save方法就报错,一个update方法就修改了,一个delete方法就删除。
    6. 全自动的持久层框架。
    7. 但是,hibernate是有史以来学过的最难的东西。
    8. 配置文件当中一个标签当中,级联,懒加载,各种属性。
    9. 用它只会试错,根本不知道咋生效的。
  4. spring:
    1. 它应该叫什么框架呢?不同人有不同的叫法。
    2. 有的人叫做整合型框架,还有人叫做设计型框架。
    3. SSH当中,SSM当中,都用到了spring。
    4. 不用spring也可以,但是用了spring之后,项目更完善。
    5. 项目当中加入spring之后,发现项目写的方式跟以前不一样了。
    6. spring当中有个核心模块叫做IOC,用来管理对象的。
    7. 原来大家创建一个对象,怎么创建,就是new加上构造方法。
    8. 或者是用反射,先获得class对象,.new instance就可以了。
    9. 但是在spring当中,创建对象,是需要配置在配置文件当中。
    10. 加入spring之后,发现代码发生了根本的变化。
    11. 原来是你自己管对象,现在是交给spring管理对象。
  5. springmvc:MVC框架controller-model-view
  6. mybatis:持久层框架
    1. 半自动的持久层框架。
    2. 不像是hibernate,表不用建,sql语句不用写。
    3. sql语句必须要自己写。
    4. 写sql语句比较好。比较好维护。
    5. hibernate当中sql语句都不是你自己写的,不好控制。
    6. 全手动的持久层技术,就是jdbc,啥都要自己写。
    7. 加载驱动,创建链接,创建预编译对象,执行sql语句,这都是你自己写的。

这些框架都是开源。

开源不等于免费。

免费是不掏钱。开源就是既免费,又可以自由传播。

这六个框架当中,听说过apache吗,tomcat就是apache的。

  • structs1、structs2、mybatis都是apache开发的。

  • hibernate是JBOSS开发的。

  • spring和springmvc,是interface21开发的。

闲聊

杨博超毕业去面试,就成功了,第一次面试,面试官给了试题,都不会,就会一个html。

杨博超大学时候学的是asp、.net、c#。

c、c++、c#。

面试的时候,笔试题都不会。

上大学听说不用上课,就再也不用上课了。

手机查了两道题,就做了三道题。

面试的是总经理,公司是上海的,在郑州出差,面试。

面试的时候问公司里面是不是用c#,总经理说是,进去之后发现用的是basic。

02-spring框架简介

Spring是一个开源框架

闲聊

杨博超电脑是win10家庭版的,获取最高权限,有些文件夹权限还获取不了,专业版还是1000块钱左右。

myeclipse和eclipse不是一家公司开发的,是需要收费的。

unix操作系统是最早的操作系统,有声电影就是贝尔实验室开发的。1960到1970年左右,买一个unix操作系统要五万美元,不能随便找个机器装上,要小型机或高端服务器才能够装上。当时的小型机就能够8核,好几万美元。

所以说,开源是一个趋势。

笔记解释

  1. Spring为简化企业级开发而生,使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能。同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而在Spring中却非常的优雅和简洁。

EJB不是spring的前身,直接从jsp+servlet+jdbc切换到spring,不会很适应。

以后你什么框架都不用,但是spring肯定会用。

  1. Spring是一个IOC(DI)和AOP容器框架。

spring的两大核心,一个叫做IOC,一个叫做AOP。

当然了,说几种情况,面试给你笔试题,问你spring的核心,只有一个填空,填写什么呢?

这个时候,你填写IOC,两个填空,就填写IOC和AOP。

  1. Spring的优良特性

非侵入式:基于Spring开发的应用中的对象可以不依赖于Spring的API

依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。

面向切面编程:Aspect Oriented Programming——AOP

容器:Spring是一个容器,因为它包含并且管理应用对象的生命周期

组件化:Spring实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用XML和Java注解组合这些对象。

一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。

大家有没有听过轻量级和重量级。轻量级就是非侵入性。

jquery就是对javascript的轻量级封装。

最重要的是,并不需要让我们过渡依赖某些东西。

使用了轻量级技术之后,对你原来的技术不造成影响。你引入了jquery,还可以使用js,可以使用jquery的选择器,也可以使用document.getElementById。加入spring之后,spring可以管理对象,但是我就是想要自己new对象,都可以,这就是轻量级的意思。

IOC(DI)

IOC也可以叫做DI,DI叫做依赖注入,IOC叫做控制反转,反转控制。

IOC可以理解成为一种思想,DI可以理解成为一种实现。

英文读音的问题

语言的魅力就是他明知道你骗他的,他还相信的。

AOP

AOP是面向切面编程,OOP是面向对象编程。

因为OOP存在某些缺陷,有了AOP面向切面编程,对OOP进行补充。

AOP是为了对OOP进行补充的。

容器

spring是一个容器,管理应用对象的生命周期。

tomcat是一个容器,管理servlet的生命周期。

为什么学习spring。

没有学习spring对象之前,我们是new 构造方法创建对象。

new 构造方法一般执行一次,内存空间开辟。

如果整个复杂项目功能中,创建了1000个对象,要开辟1000个空间。

保证在整个过程中,一直用这些对象吗?不会的。

咱们有时候也不需要创建这么多的对象。

咱们讲过单例:不需要创建那么多的对象,只需要实现一个单例,就可以。

但是这个单例,我们还要自己写。

当我们使用了spring之后,咱们就可以将对象交给spring管理。

等于将对象放在spring容器中。

web容器能够管理servlet的声明周期。

spring容器就是能够管理应用对象的声明周期。

组件化

spring实现了,使用简单的组件,配置组合成为简单的应用。

每一个项目对我们来说,由各个类,由类产生对象,由对象产生方法,实现功能。

将所有用到的类,全部交给spring管理,然后把这些类叫做组件。

spring当中的组件就是spring管理的对象

原来我们需要什么对象,就创建什么对象。现在不是的。现在spring把我们需要用到的组件拼装起来。

spring能够降低程序的耦合,让类与类之间的关系,不是那么强大了。

组件化,可以理解为降低耦合。

一站式

在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。

  • spring
  • spring mvc
  • spring jdbc
    • mybatis

spring这个家族真实牛逼。

03-spring简单案例1

spring当中的图

image-20211001103142518

从下往上看,最基本的叫做core container

  • beans
  • core
  • context
  • spel

最下面,最基本的就是beans,管理beans的,就是ioc。

  • AOP - 面向对象编程
  • Aspects - 切面的意思
  • Instrumentation
  • Messaging - 消息队列,管理消息的。

数据访问层

  • JDBC:java数据库连接
  • ORM:object relation mapping 对象关系映射,经常用在持久层框架中。
    • 原来是需要sql语句,查询数据,把查出来的数据放到对象中,再处理对象。
    • orm是持久层框架中,最主要的核心,从数据库查出来的数据,自动赋值给对象。rs = result.set,不需要这个过程。
    • 大的关系来说,操作数据库中的数据,像是操作实体类一样简单。
    • hibernate、mybatis
  • OXM
  • JMS
  • Transactions

  • Websocket

  • Servlet

  • Web

  • Portlet

这就是以后要讲的springmvc框架,特别方便简单,大家原来用servlet的时候,获取客户端数据是request.getParameter。springmvc当中只需要在处理请求的方法上,加上参数就可以自动获取。还比如说,大家原来都用过ajax,都学过json,我通过ajax获取java中的对象的时候,能直接获取吗?不能,需要先转换成为json,然后响应。原来你转换json,需要用到一个工具类,这些工具类是特别多的。比如说jackson。也是处理json,还有阿里巴巴开发的fastjson,这个东西,杨博超用的比较多,非常方便,json.toJson就好用。

在springmvc当中转换json的过程,根本就不需要你写。自动转换为json。

这个图,大家可以简单理解一下。

写一个spring的小项目

把spring的运行原理要记到脑子当中。

工具

image-20211001105314835

这个东西是eclipse的产品。

不要钱的。

这个东西,跟eclipse有什么区别。

STS是专门为spring来设计的。

给spring提供了非常多的方便。

image-20211001105435465

安装jdk1.8

访问网站:https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html

image-20211001105705331

安装tomcat7

参考这个文章:https://blog.csdn.net/louisgod/article/details/76092950

使用STS

image-20211001112153643

咱们选择java视图。

不需要的视图,都关闭掉。java项目是需要用到一个控制台。

image-20211001112240721

简单设置sts

image-20211001112621572

image-20211001114128873

image-20211001114149721

image-20211001114328996

image-20211001114405481

image-20211001114430230

资料

image-20211001114454952

image-20211001114601051

  • 每3个是一个jar包。
    • 第一个是jar包
    • 第二个是doc文档
    • 第三个是源代码

  1. 加入JAR包

① Spring自身JAR包:spring-framework-4.0.0.RELEASE\libs目录下

spring-beans-4.0.0.RELEASE.jar ---------------这就是IOC的功能

spring-context-4.0.0.RELE2ASE.jar------------上下文

spring-core-4.0.0.RELEASE.jar--------------核心jar包

spring-expression-4.0.0.RELEASE.jar-----------表达式

② commons-logging-1.1.1.jar

web项目jar包可以放在lib当中,java项目,咱们放在哪里呢?

我们可以新建一个文件夹。

image-20211001133826692

source folder是放源文件的。

folder是放普通文件的。

commons-logging

有时候发现,写某些功能,大部分都导入日志jar包。

但是导入日志jar包,根本没有用,确实会输出一些日志。

为什么?

这个jar包不需要管。

框架当中默认使用某些日志功能的。

比如mybatis,apache开发的。apache当中有一个log4j的jar包。

apache还开发了一个dom4j,这里的4就是four,就是for,j就是java。

j2ee当中的2就是to。

i18n就是国际化。

加载jar包

image-20211001134416816

创建一个sourcefolder

image-20211001134511529

src当中创建一个类

image-20211001134629371

以后类中不要用基本数据类型了

为什么呢?

mysql当中不给字段赋值,默认就是null,从数据库查出来就是null。

如果你的类的字段是int,null是不能给int赋值的。

这是第一个问题。

实体类中的属性,可以赋值,也可以不赋值。

不赋值,int就是默认值是0。

double是0.0。

所有的引用类型都是null。

如果类属性是int,我主动设置为0,或者默认是0,业务意义是不一样的。

所以以后不要再用基本数据类型了。直接用包装类。

int就是integer

char就是character

double就是double

boolean就是boolean

设置set和get方法和toString

image-20211001140807183

写测试类

image-20211001140911809

然后写一个单元测试。

Junit最主要的用处,就是不需要写那么多的main方法,只要加一个@test注解,就可以执行方法。

正儿八经没有学习到junit的精髓。

现在我们使用junit就是为了每个方法都可以执行。

image-20211001141104755

这个时候,可以为属性赋值。

image-20211001141240595

这就是原来的一种方式。

需要交给spring管理

需要把对象,交给spring管理

需要在配置文件当中进行对象的配置。

我们接触的最早的配置文件,就是web.xml,这被称之为入口配置文件。

只有web.xml被加载成功了,项目才能够正常执行。

web.xml配置servlet的时候,少写了一个斜线,多写了一对标签,这样启动都启动不起来。

web.xml是在web项目当中占据了非常大的作用。

框架当中也是的。

咱们刚才说的六个框架,都是xml作为配置文件的。

咱们需要创建一个配置文件,把对象配置到配置文件当中,才可以说,对象交给了spring管理。

创建xml

image-20211001141913598

image-20211001141939425

xml非常非常厉害,是叫做可扩展标记语言。

什么意思。

可以看到web.xml和spring的xml根本不一样。

会发现xml扩展性特别强大。

所有的标签都是需要你自己定义的。

什么叫做可扩展,这里面没有任何的提示。

所有的标签都是自己定义的。

使用sts创建xml

image-20211001142320125

image-20211001142351838

applicationContext.xml

这是spring默认的配置文件的名字。

这个名字是spring配置文件默认的名字。

等到大家做SSM整合的时候,需要把加载spring配置文件的过程,放在web.xml当中。自动加载spring的配置文件,需要加载这个名字的配置文件applicationContext.xml。

image-20211001142606331

beans标签当中写的玩意,叫做命名空间。

命名空间是,规定你的xml当中,能够写什么标签,不能写什么标签。

bean

image-20211001142806201

这个bean不是javabean,这个bean就是对象。

bean代表的是对象,对象由类而来,类的实例化就是对象,我们要规定这个对象,由哪个类,实例化的。

我们的bean标签里面要有class属性,class属性的值,是一个全类名。

image-20211001143000420

到这里,下课了。

04-spring简单案例2

写一个测试类

image-20211001143102612

如何获取spring管理的bean

第一步,初始化容器。

spring管理的bean,就是放在spring的容器中。

我们要获取spring的容器对象ApplicationContext。

image-20211001143233050

这是一个接口,接口不能直接实例化,我们需要通过接口的实现类来进行实例化。

image-20211001143409916

接口的实现类是ClassPathXmlApplicationContext,这个实现类有一个重载方法,里面是放置configLocation,就是配置文件的路径,我们的配置文件是在conf下面的。

conf下面的东西,最终是会加载到类路径下面的。

image-20211001143556700

配置文件的名字是可以改的。

通过容器获得对象

image-20211001143656175

spring当中管理多个bean,我们怎么通过ApplicationContext获得对象呢?

我们可以给bean加上一个id属性。

id属性是唯一标识,只要保证不重复,就可以了。

image-20211001143810026

获取bean对象的时候,通过id获取。

image-20211001143842954

在这个IDE当中,通过ctrl+1获取返回值。

或者使用快捷键alt+shift+l

返回值是一个Object呢?

只有当代码执行的时候,执行过程中,执行到这一步了,才知道bean是一个Person类型。

在代码编写的时候,直接写的是Object。

我们可以强制类型转换一下。

Object是所有类的直接父类或者间接父类。

向下转型和向上转型

咱们都学过向下转型和向上转型。

向上转型:

通过子类的构造方法,创建父类的对象。

通过实现类的构造方法,创建接口的对象。

向下转型:

将上转型对象/父类对象,强制转换为子类对象。

image-20211001144246205

这样我们就通过容器的getBean方法,从spring中获取了对象。

image-20211001144343626

现在看到了Spring创建对象的过程。

  1. spring配置文件当中,配置相应的bean,配置class和id属性
  2. 初始化容器
  3. 通过容器的getbean方法获取对象

spring管理对象怎么属性赋值-property标签

通过配置文件当中的子标签,给属性进行赋值。

image-20211001144633545

再执行一下:

image-20211001144714874

这就是spring管理bean的写法和过程。

05-spring配置介绍

看文档

  1. 在Spring Tool Suite工具中通过如下步骤创建Spring的配置文件

​ ① File->New->Spring Bean Configuration File

​ ② 为文件取名字 例如:applicationContext.xml

这个配置文件的名字是可以改变的。

  • 因为初始化容器的时候,要写配置文件的路径和文件名。
  • 写成什么名字,初始化的时候,名字写进去就可以了。

image-20211001144856311

image-20211001144926114

IOC和DI

image-20211001145033618

  • 控制反转,就是一个思想。
    • 我们需要了对象,我们就创建对象,为属性赋值,然后使用对象。
    • 我们把对象交给spring管理,我们只是配置了一下对象,我们并不知道对象是怎么创建的、赋值的,我们只是可以获取可以使用的。
    • 控制反转就是我们对对象的控制权,交给了程序本身。
    • 这是一种思想。
    • 自己做饭和外卖的举例。
    • 如果你要写单例的时候,要把构造方法私有化,提供一个的公共对外访问点,但是spring管理的对象,可以自由设置是单例的还是多例的。只需要用到一个属性。

spring的单例属性

image-20211001145427858

singleton就是单例。

prototype就是原型,就是多例。你每次new构造方法,就要分配空间,要创建对象。

在java当中对象模式,是多例的。

DI

image-20211001145703576

什么叫做依赖,对象和对象,对象和属性的关系。

我要创建一个对象。

这个对象依赖另外一个对象。

咱们有了spring之后,对象不需要咱们维护,对象的关系,也不需要咱们维护。

什么叫注入,注入就是赋值。

比如说car对象依赖发动机对象,方向盘对象。

普通的完成过程,在car的内部,new一个方向盘对象,发动机对象,这就是普通的做法。

注入就是,依赖谁,就注入谁,就是为谁赋值。

刚才的例子,依赖两个属性,所以就给属性进行赋值。

IOC就是一种思想,DI就是具体的实现方式。

写一下笔记

  • bean标签是用来定义,spring所管理的一个对象。
  • id属性,代表该对象的唯一标识,不能重复。
  • class属性,需要写此对象所属类的,全限定名。
    • 全类名,就叫做全限定名。
    • 就是包名字+类名。
  • property标签,为对象的某个属性赋值。
    • name就是对象属性名。
    • value就是对象属性值。

image-20211001150310916

getBean

getBean有多个重载的方法。

同名不同参数的方法,就是重载方法。

image-20211001150400672

看第一个方法,就跟反射相关。

什么时候学过Class对象。就是反射的时候。

获得Class对象的三种方式

  • Class.forname

  • 对象.getClass

  • 类名.class

getBean

我们可以通过类型对应的class对象,也可以获取对象。

image-20211001150556611

image-20211001150613298

如果我们用这种写法,跟id没有什么关系。

我们在配置文件当中,将对象的id删除,也是可以正常获取到的。

配置文件当中的bean的id

id可以不设置,通过类型Class对象获取bean的过程中,可以不设置。

举例配置一个Class的两个对象

image-20211001151749195

如图所示,我们配置了Person的两个对象。

我们在getBean的时候,怎么获取?

image-20211001151851855

如果是这样,就报错了:

image-20211001152054049

说一个事情

把所有遇到的错误,复制下来记录到一个文档当中。

错误记录

十月 01, 2021 3:37:41 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4783da3f: startup date [Fri Oct 01 15:37:41 CST 2021]; root of context hierarchy
十月 01, 2021 3:37:41 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.atguigu.spring.mod.Person] is defined: expected single matching bean but found 2: PersonOne,PersonTwo
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:312)
	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:985)
	at com.atguigu.spring.mod.TestBySpring.main(TestBySpring.java:10)

通过Class获取bean

如果你在配置文件当中,配置了两个一个类的对象,这个时候,如果你getbean的时候,通过class获取bean,容易出现下面的错误。

NoUniqueBeanDefinitionException

闲聊

有个人,在航空公司做培训。

把工作当中遇到的所有问题,记录到本子上。

换工作的时候,换到另外的航空公司,这个公司领导不让走。

要么把本子留下来,要么人留下来。

公司开的条件,你只要不把本子给别的公司用,给你涨工资,你想去哪里去哪里。

getBean(xxx.class)

使用这个方法获取对象的时候,要求spring管理的此类型的对象,只能够有一个。

getBean(String arg0,Class<T> arg1)

以后推荐大家使用这个方法,来获取bean。

image-20211001154214473

大胆想想spring是怎么为我们创建对象

咱们将对象以bean标签的方式,写到了配置文件当中。

我们初始化容器的时候,就会加载配置文件,读取配置。

怎么根据标签,就创建了对象了呢?

反射当中有一种获取class的方法,叫做class.forName(全限定名),通过获取的class对象.newInstance方法,就可以创建对象。

所以,我们推测spring是通过反射的newInstance方法来创建对象的。

验证spring原理

new Instance方法创建对象的时候,有一个条件,类必须要有无参构造器

我们现在的Person对象当中有构造方法吗?

image-20211001154616115

这里有一个缺省的,默认的构造方法,是无参的。

我们创建一个有参的构造方法:

image-20211001154650169

image-20211001154703074

image-20211001154721232

这个时候,就有了。

然后我们再测试一下通过Spring来获取对象。

image-20211001154804303

这个时候,就报错了:

image-20211001154824712

错误记录

十月 01, 2021 3:48:59 下午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4783da3f: startup date [Fri Oct 01 15:48:59 CST 2021]; root of context hierarchy
十月 01, 2021 3:48:59 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'PersonOne' defined in class path resource [applicationContext.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.atguigu.spring.mod.Person]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.atguigu.spring.mod.Person.<init>()
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1076)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1021)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at com.atguigu.spring.mod.TestBySpring.main(TestBySpring.java:9)
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.atguigu.spring.mod.Person]: No default constructor found; nested exception is java.lang.NoSuchMethodException: com.atguigu.spring.mod.Person.<init>()
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:85)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1069)
	... 13 more
Caused by: java.lang.NoSuchMethodException: com.atguigu.spring.mod.Person.<init>()
	at java.lang.Class.getConstructor0(Unknown Source)
	at java.lang.Class.getDeclaredConstructor(Unknown Source)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:80)
	... 14 more

这个错误,叫做:NoSuchMethodException

学习反射的时候,经常见到这个错误。反射当中什么情况下,会遇到这个错误。

getDeclardMethod的时候,会遇到这个错误。

分析

这里这个错误是什么意思呢?

如果以后在spring当中遇到错误,别的不用看,就看最后一个,就是最根本的问题。

原理解释

我们给类当中写了一个有参构造方法,这样就将原来的无参构造方法,覆盖掉了。

这说明了,spring就是根据反射的原来,来创建对象的,是需要用到newInstance方法的。

newInstance方法是要求类当中必须要有无参构造器的。

image-20211001155417378

补充上去无参构造器之后,再测试,就正常了。

image-20211001155711741

文档

image-20211001155742543

我们通过ctrl+shift+t,为了open type。

image-20211001155825712

image-20211001155842307

image-20211001155859928

image-20211001155923367

这是一个接口。

极端的抽象类,就是一个接口。

抽象类当中可以存在抽象方法。

接口当中全部都是抽象方法。

image-20211001160026464

image-20211001160051575

image-20211001160128084

image-20211001160137889

不看这个BeanFactory.class的源码。

我们看一下ApplicationContext的源码。

image-20211001160741439

然后在这里按照ctrl+t,就出来这样的东西:

image-20211001160835222

可以看到整个的继承实现关系。

image-20211001160911656

可以看到最顶层的接口,叫做FactoryBean。

我擦,不是BeanFactory吗?

再来一次。

image-20211001161021670

打开是这样的:

image-20211001161048783

image-20211001161333831

这里就是BeanFactory了。

刚才是咋回事?

不知道。

这就列出来了所有的实现继承关系。

BeanFactory下面有一个子接口,叫做ApplicationContext。

ApplicationContext下面有一个ConfigurableApplicationContext。

咱们使用的是这个接口的实现类,就是ClasspathXmlApplicationContext。

还有一个实现类,叫做FileSystemXmlApplicationContext。

两个的区别是:ClasspathXmlApplicationContext,这个配置文件是在项目当中的,是在类路径下的。

如果你有一个文件服务器是专门用来放文件的,如果你要加载文件服务器上面的配置文件,就要用到FileSystemXmlApplicationContext。

  • ClasspathXmlApplicationContext:这里面写的是相对路径。
  • FileSystemXmlApplicationContext:这里面写的是绝对路径。

笔记

image-20211001161829087

image-20211001161846398

最后的讲解

image-20211001162009244

这里提示我们从来没有关闭过。

关闭一般都是close方法。

image-20211001162059831

但是我们发现,根本就没有close方法。

ApplicationContext是一个接口,这个接口是没有一个关闭的方法的。

我们可以去它的子接口当中找一找,到底有没有关闭的方法。

接口越往下继承,功能约全的。

image-20211001162334394

这个时候,我们就发现了ac是有close方法的:

image-20211001162416274

我们也可以直接这样用:

image-20211001162458743

2019年6月11日 - 星期二 - 上午结束

06 - 注入方式

2019年6月11日 - 星期二 - 下午开始

image-20211001165243502

  • 老师将上午的内容复述了一下。

image-20211001165618493

image-20211001165819434

这个webApplicationContext,这个是我们使用springmvc的时候,才会使用到的。

给bean的属性赋值

image-20211001165920452

内容还是非常多的。属性,其实就是一个变量。

属性要有类型。

java当中的类型,挺多的。基本数据类型,引用数据类型。

引用数据类型当中,包含一些基本的包装类,还有集合,数组。

给bean的属性赋值,早上的时候,就是依赖注入的过程。

IOC叫做把程序员对一个对象的管理权,反转给程序本身。

依赖注入,把具有依赖关系的属性进行赋值。注入就是赋值。

依赖注入的方式有好多种,咱们就讲解两种。

第一种叫做set注入,第二种叫做构造方法注入。

写一个简单的小例子。

image-20211001170156243

设置一些属性。

image-20211001170231875

设置set和get方法,然后给一个toString方法。

创建配置文件。

image-20211001170336357

image-20211001170818829

这也是咱们起名字的时候,经常会用到的一个名字。

image-20211001171313386

image-20211001171456979

image-20211001171514602

问题

对象的属性都是私有的。

访问修饰符:private、默认的、受保护的、公共的。

设置为private,能够直接访问吗?不能够的。

property标签是通过什么方式,给属性赋值的呢?

应该是set方法。

image-20211001171638630

点进去,看到下面:

image-20211001171707235

我们在property标签当中设置的id,主要对应的是对象的set方法当中,setId的名字。不是对应,对象的属性名字。

修改

image-20211001171817499

这种情况,我们测试,也是可以成功赋值的:

image-20211001171851389

所以,严格上来说,property当中的id,并不是对应对象的属性名字,而是对象的set方法。

以后的配置基本上都是用这一种的。

另外的方式 - 构造器

在对象当中写一个无参和有参的构造方法:

image-20211001172029021

我们可以通过有参构造器,可以给属性赋值。

这个就是通过局部变量为全局变量赋值。

spring当中为属性注入的时候,也可以通过构造方法注入。

再演示一下

image-20211001172212885

image-20211001172301577

image-20211001172332933

image-20211001172338874

成功赋值了,为什么呢?

在对象当中有一个四个参数的构造方法。在constructor-arg,会自动匹配到实体类当中相对应的构造方法。

如果我们修改有参构造器:

image-20211001172440421

image-20211001172454722

配置文件直接报错,因为在student当中,只有一个无参构造和三个参数的构造方法。

进一步演示

给student对象添加一个score属性:

image-20211001172612331

然后我们多写一个有参构造器:

image-20211001172735363

这样对象当中都有四个参数的两个构造器。

那么我们在配置文件当中,也是可以使用第二个构造方法来赋值的:

image-20211001172928716

测试一下:

image-20211001173001267

结果是:

image-20211001173013171

正常的。没有报错。

但是s3当中的90,我是想要赋值给score的,但是赋值给了age。MLGB。

这是为什么呢?

image-20211001173132030

这是因为你写的90,90就是一个int类型。所以赋值给了age。

怎么处理呢?

image-20211001173234260

我们设置一下属性的index和type。

这个时候,再通过构造方法匹配的时候,就会匹配到正确的构造方法了。

下面是测试结果:

image-20211001173319354

如果使用构造方法赋值的时候,出现了数据的混淆,这个时候就要加上index和type。

这里的index就是bean标签对象当中的index。

这里看到constructor-arg,知道这是构造方法赋值,就可以了。

后面咱们用得最多的,还是property标签。

07-p命名空间

constructor-arg标签(这一块没有讲解视频)

image-20211001163334541

笔记

image-20211001162614367

image-20211001162651712

  • 依赖注入的方式
    • 通过bean的set方法赋值(property标签)
    • 通过bean的构造器赋值(constructor-arg)
      • 自动匹配合适的构造器
      • 通过索引指定参数的位置。(一般情况下,不会单独使用,一般都是idnex和type结合在一起使用)
      • index和type结合

image-20211001162957982

image-20211001163044422

  • 这个p命名空间,是在spring2.5之后引入的。
  • xml的命名空间,是为了规定xml当中能够写某些标签的。命名空间的作用,规定当前的配置文件当中只能写什么,写什么有意义。

p命名空间

image-20211001163213879

点击namespaces,点击p。

image-20211001163248870

这个时候,就会发现xml文件当中多了一行:

image-20211001163310044

image-20211001163601506

这个时候,就可以来用p命名空间了。

引入了p命名空间之后,就不需要使用property标签了,直接在bean标签当中,通过p:属性来进行赋值。

image-20211001163626484

这种方式也记住。

  • property
  • constructor-arg
  • p命名空间

这三种方式,都要知道,真正用的时候,可能就是property的。

08 - 字面量和ref

可以使用的值

image-20211001173620795

这里说的意思是,为属性赋值的时候,可以使用的值。

字面量就是,你能够把这个值,写成字符串的方式的,就叫做字面量。

所有的基本数据类型,以及基本数据类型的包装类,以及string。这些都是字面量。

但是引用数据类型是不可以的。

配置文件中可以通过value属性或者value子节点的方式指定的

image-20211001173824466

image-20211001173844682

可以通过value直接赋值的,就是字面量。integer,double,string都可以,这都可以叫做字面量。

举例

image-20211001173953253

image-20211001174012212

需求:现在要为学生对象,分配一个老师

在java当中如何表示?

是可以在student当中,创建一个Teacher类型的属性。

大家都做过增删改查,表和表之间的关系,多对一,一对多,一对一,多对多。

学生和老师是多对一的。

在多的这一方,就是学生这一方,设置一个一的属性,就是老师的属性。

一对多的时候。

在一的这一方面,就是老师的这一方,设置一个多的集合,就是学生的集合。

image-20211001174324419

在spring的配置文件当中怎么表示呢?

怎么赋值

image-20211001174436907

这个时候,是不能够通过value来赋值的。

value只能够赋值字面量。

不能够使用value。

我们应该怎么做呢?

我们需要创建一个对象,通过对象来给teacher属性赋值。

spring管理teacher对象

这个时候,让spring管理一个teacher对象。

image-20211001174614587

设置teacher对象的属性。

image-20211001174702857

ref属性

这个属性的意思,叫做引用的意思,作用就是引用当前spring管理范围之内的bean的id。

image-20211001174813901

这里ref之后的teacher,表示的就是spring管理范围之内id为teacher的对象。

测试一下

image-20211001174901329

总结

给属性赋值,第一种叫做字面量,通过value属性,第二种叫做引用类型,通过ref属性。

p命名空间当中也有类似的ref的机制。

image-20211001175001545

image-20211001175039994

按着ctrl键,直接定位到这个地方。

image-20211001175107080

笔记

image-20211001175153851

image-20211001175207225

级联大家有没有听说过?

就是一级一级的联动效果。

举个最简单的例子,叫做三级联动。

比如京东,淘宝,美团买东西。选择地址的时候,每选择一级,都是有联动效果的。

选择了省份之后,就要选择地级市,然后就要选择地级市下面的县。

student当中包含teacher对象,teacher对象当中包含tid和tname属性。

image-20211001181112860

测试结果:

image-20211001181228915

这个就是叫做级联属性赋值。属性中包含一些属性。

image-20211001181324871

09 - 集合属性赋值

image-20211001181442227

有没有学过内部类?

内部类有几种写的方式:

  • 全局内部类
  • 成员内部类
  • 静态内部类
  • 匿名内部类

内部bean和内部类,不是一个意思。

闲聊

大家感觉哪里的方言最难听懂的。山西的方言很难听懂。

一个村和一个村都不一样。

原来同事山西的,出去玩接电话,根本听不懂。

以后尽量说普通话。

念个html,都是he,te,mo,le。

安装oracel的时候,有个默认的用户,叫做scott,有人就年做斯考特。

说起来oracle,不得不吐槽,关系型数据库,这东西应用价值非常高。咱们用mysql,以后可以接触oracle。

大公司都是用oracle。前几年来钱慢,都用mysql,但是性能不行,开源免费。

oracle本来性能就很强大,想在公司里面用。好几百万。

真的就是这样的。但是咱们学习的时候,装普通的oracle,特别脆弱,特别大。

跟你电脑性能没有特别大关系,最少20分钟安装。

虽然mysql卸载就够麻烦的了,还要删除注册表什么的。

oracle卸载最少也要10分钟左右。

就是这样的。

mysql就一个服务。

oracle装完,一共是7、8个服务。有三个启动才能用的。

杨博超当时电脑是4G内存,360的加速球,直接飙99%。

写一行代码,咔咔打完了,半分钟,打的内容才会一点一点出来。

oracle非常脆弱,没过两天,一开机,说没了。网上说360把它当病毒删除了,特别麻烦。

教学过程中,也是,没两天就没了。

能删除oracle的东西太多了,比如网游加速器。

网游加速器原理就是把你不用的服务,关闭掉。

安装oracle之前,先检查学生有没有安装网游加速器。

内部bean

再创建一个student的bean,给teacher属性赋值的时候,还有内部bean的写法:

image-20211001183335770

例如上面的图中,我们可以在ref引用对象的时候,直接写一个内部的bean。

  • 其实这个内部bean的只属于,包含它的对象。
  • 然后其他的bean对象,是不能够引用这个内部bean的。

定义在某个bean内部的bean,只能够在当前bean中使用。

集合属性

之前我们一直都是在讲依赖注入的内容,DI就是给属性赋值。

  • 字面量
  • ref
  • 内部bean

如果说,咱们学过的集合:list、set、map还有数组,咱们怎么用spring实现呢?

在teacher对象当中定义一个list集合。

image-20211001224214598

知识小回顾

集合的根接口是collection,collection跟list和set的关系,是什么?

list和set是继承了collection,list和set也是接口。

接口和接口只能继承。

类和类之间只能继承。

类和接口之间才能够实现。

list这个接口,根据实现方式,有几个实现类,三个。ArrayList、LinkList、Vector。

set是有一个hashSet还有一个TreeSet。

HashSet按照hash值排序。

TreeSet按照自然序升序排序。

Map是有两个实现类,hashMap和hashTable。

hashTable用得不多,但是hashTable有个子类,叫做Properties,这个类用得比较多。

这个Properties类最基本的功能,跟hashTable一样,都是键值对存在。

在java当中有Properties文件,Properties类,就是操作Properties文件,有两个方法,store是保存,load是加载。

小演示

image-20211001224820141

这个集合用来存储老师教的班级。

spring配置list集合属性

然后在spring当中,通过配置管理teacher这个对象。

image-20211001225625294

测试一下:

image-20211001225715028

在编程语言当中,如果你写四个0,数字前面的0是没有意义的,数字后面的0才是有意义的。

IO流举例

大家学io流的时候,从文件当中读取内容的时候,读出来的是什么?

比如说字节流,一次可以只读一个字节,当然你也可以把它放在一个数组当中。

一次只读一个字节的情况,通过read方法返回值是int类型,代表的是字节对应的ASCII码。

一个字节占8位,一个int类型相当于4个字节,就是32位。

这里面就有一个过程,就是需要把你读出来的8位,转换成为32位。

怎么转换,前面加24个0。

这就叫做“高24位补0,低8位取值”。

表示老师和学生的关系

一个老师可以有多个学生。

大家都做个什么项目。

做过多对一的吗?

做过单表的增删改查。

多对一的增删改查。

一对多的增删改查。

表关系就四种。

表示老师所教的学生

image-20211001232731616

如果在Teacher对象当中设置,如上的student的list对象,可以吗?

spring进行set注入的时候,找到的,并不是类当中的属性名,而是找到的对应的set方法的名字。

image-20211001232848958

按照正规的命名方法,set和get的方法名字,应该是这样的:

image-20211001232936153

所以,如果你取名的时候,是类似sList这种名字的话,自动生成的set和get方法的方法名字,是不满足规则的。

所以,如果你真的叫做sList,你自动生成了set和get方法之后,没有修改名字,那么你的set和get根本就没有效果。

咱们可以尝试一下。

小测试

我们上面不修改set和get方法的情况下,直接在spring当中配置bean对象,类似这样:

image-20211001233354386

配置的时候,直接报错。报错说明,里面没有任何一个set方法能够为这个sList属性赋值。

结论就是,实体类当中起名字的时候,属性绝对不能够使用sList这种名字。

修改一下

image-20211001233532299

image-20211001233548737

这个list标签当中应该放的是,student对象,能够用字面量解决吗?不能够的。

对引用数据类型的赋值,可以使用ref,可以使用内部bean。

image-20211001233854934

image-20211001233904196

image-20211001234152330

测试的效果是这样的:

image-20211001234243867

这里就是操作list集合的方式,spring管理的方式。

小总结

image-20211001234345434

小任务

spring管理数组,spring管理set,要去尝试一下。

其实也没有啥好尝试的,文档当中写的都有。

image-20211001234430748

算了,还是讲解一下吧。

数组

image-20211001234456148

为数组属性赋值,可以使用array标签,也可以使用list标签。

为什么呢?

arrayList的底层用的就是数组。

set

image-20211001234653935

value给字面量赋值。

ref或者bean标签给引用数据类型赋值。

map

map比较学习的list或set都比较复杂。

因为map当中的元素,都有键值组成。

演示map

image-20211001234903714

给Teacher对象,设置一个map属性。

键写成编号,值写成名字。

然后开始配置spring配置文件。

image-20211001235027148

image-20211001235039922

  • description是描述的意思
  • entry是入口的意思
    • 如果大家对map了解,就知道map为我们提供了很多,遍历键,遍历值,遍历键值对的方法。
    • 比如说:
      • keyset():获得所有的键
      • value():获得所有的值
      • entryset():获得所有的键值对
    • entry代表的就是一组键值对。

image-20211001235750131

image-20211001235921649

image-20211002000256986

测试一下:

image-20211002000335466

总结

image-20211002000448908

10 - 集合类型的bean

小引子

我们上面对bean的集合属性,的处理方法是,在bean当中通过list标签,array标签,set标签,map标签构建对应的集合。

还有其他方法吗?

能够在properties当中,通过ref来引用list,array,set,map对象吗?

也就是说,能够在spring内部直接创建和管理list,array,set,map对象吗?

演示一下

如果我们想要使用ref,或者说,我们想要spring直接管理一个list对象。

我们需要这样写:

image-20211002001138198

需要用到util工具。

image-20211002001205710

c:foreach,在jsp中使用c标签的时候,见过prefix。

image-20211002001314417

image-20211002001354554

  • 右边就是各种不同版本的xsd文件。
  • 向下兼容:spring我们使用4.0,4.0的jar包,可以使用4.0以下的所有xsd。
    • myeclipse10,还有myeclipse8.5,如果你把myeclipse 10激活了,8.5就自动激活了。
    • office高版本的,绝对能够打开低版本的文件。
    • 这个就叫做向下兼容。
  • 什么是xld
    • 相当于标签库一样。
    • spring当中看到的是xsd文件
    • mybatis当中的标签库是dtd文件
    • 这两种里面存的都是标签。
    • 在一个xml文件当中引入了xsd文件或者dtd文件之后,才能够在xml当中使用这些标签。

image-20211002001811764

image-20211002001908985

测试一下:

image-20211002003613504

错误记录

十月 02, 2021 12:35:07 上午 org.springframework.context.support.ClassPathXmlApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@4783da3f: startup date [Sat Oct 02 00:35:07 CST 2021]; root of context hierarchy
十月 02, 2021 12:35:07 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [beans-di.xml]
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 't1' defined in class path resource [beans-di.xml]: Initialization of bean failed; nested exception is org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.ArrayList' to required type 'java.util.ArrayList' for property 'students'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.util.ArrayList] to required type [com.atguigu.spring.test.Student] for property 'students[0]': no matching editors or conversion strategy found
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:304)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:300)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:700)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
	at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
	at com.atguigu.spring.test.TestBySpring.main(TestBySpring.java:10)
Caused by: org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.util.ArrayList' to required type 'java.util.ArrayList' for property 'students'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.util.ArrayList] to required type [com.atguigu.spring.test.Student] for property 'students[0]': no matching editors or conversion strategy found
	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:473)
	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:509)
	at org.springframework.beans.BeanWrapperImpl.convertForProperty(BeanWrapperImpl.java:504)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.convertForProperty(AbstractAutowireCapableBeanFactory.java:1502)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1461)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1197)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
	... 11 more
Caused by: java.lang.IllegalStateException: Cannot convert value of type [java.util.ArrayList] to required type [com.atguigu.spring.test.Student] for property 'students[0]': no matching editors or conversion strategy found
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:267)
	at org.springframework.beans.TypeConverterDelegate.convertToTypedCollection(TypeConverterDelegate.java:537)
	at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.java:202)
	at org.springframework.beans.BeanWrapperImpl.convertIfNecessary(BeanWrapperImpl.java:458)
	... 17 more

这个错误的类型,叫做:Cannot convert value of type。

这是类型转换的问题,不能够将list转换成为student。

image-20211002003727698

咱们这里的配置是要将list赋值给students属性的。

这个属性是一个list集合,里面放置的是student对象。

通过这个错误,简单判断出来,当我拿着list标签定义的这个list集合,给实体类的list属性赋值的时候,出现了类型转换的问题。


类型转换

基本数据类型当中的,小转大,是自动转换。大转小,是需要强制转换。

引用数据类型的时候,可以类型转换吗?通过子类的构造方法,实现类的构造方法,能够创造父类的对象,或者是接口的对象。

这个就是转换。

然后能够将上转型对象,强制转换成子类对象,这个就是强制转换。

image-20211002004401032

解释上面的报错

util:list当中的list标签定义的list对象,是无论如何都不能够转换成为student对象的。他们两个对象之间没有继承,也没有实现的问题。

util:list本身代表的就是一个集合,这个util:list当中的元素,就是student元素了。

去掉util:list当中的list标签之后,就测试正常了:

image-20211002004630917

utils

image-20211002004706736

utils可以操作map,可以操作set,也可以操作properties。

properties和map不一样吗?

不一样的。虽然说map是接口,实现类有一个hashTable,hashTable有一个子类叫做Properties,Properties当中的键和值,都只能够是字符串类型。但是map的键值都可以是object类型,代表的是任意类型。

utils操作map

map当中一个entry代表的是一个键值对。

image-20211002005122219

Teacher对象当中有list类型的属性,也有map类型的属性:

image-20211002005200009

我们都可以在spring的配置文件当中进行DI,使用utils。

  • 第一种方式:我们可以直接在,给集合属性赋值的时候,通过list或者map标签来进行赋值。
  • 第二种方式:我们也可以利用utils来单独创建一个表示集合的bean。

11 - FactoryBean

笔记

image-20211002005432178

factory是工厂,bean是对象,factoryBean就是对象工厂。

spring当中的IOC,用的是什么设计模式呢?

就是工厂模式。

最底层的接口,叫做BeanFactory,就是工厂模式。

我们不在乎他们是怎么为我们创建的对象。我们需要对象的时候,直接从工厂当中获取就可以了。

设计模式

大家学过什么?

单例,工厂。

工厂模式就是很简单:来隐藏类创建的过程。创建对象的时候,不需要自己去创建,通过工厂去获取。

至于类创建的过程,去工厂当中体现,不在我们获得对象的时候,体现。

明天我们就要学习一个代理模式。

spring当中的AOP用的,就是代理模式。

这个也是非常重要的,也是有一定的难度的。

明天所写的代码,能够记住就记住,记不住就背下来。

FactoryBean

image-20211002005745898

FactoryBean是一个接口,我们创建一个类,实现了这个接口,那么这个类,就是FactoryBean。

用法是怎么样呢?

演示

image-20211002010030908

image-20211002010103526

image-20211002010144258

创建一个工厂类

image-20211002010241122

然后我们需要让我们的工厂类,实现FactoryBean这个接口:

image-20211002010440623

这个接口是有泛型的,泛型就是我们的工厂是要创建什么类型的对象的。我们这里是Car类型的。

这里的错误,解决的时候,有几种方式呢?

为什么报错了,因为现在实现这个接口的,是一个普通的类。实现就相当于另类的继承。

实现一个接口,接口当中的抽象方法也会,继承给它的实现类。

这个实现类当中有三个抽象方法。普通类当中是不能够存在抽象方法的。

所以报错了。

第一种解决的方法:加上abstract关键字,把普通类,变成了抽象类。

image-20211002010708297

第二种解决方法:普通类当中不能够存在抽象方法,我们就对抽象方法进行重写。

image-20211002010822393

image-20211002010831377

第一个方法,叫做getObject,获取对象的方法。

第二个方法,叫做getObjectType,获取对象类型。所属类。

第三个方法,是否为单例的。如果返回false不是单例,如果返回true,是单例。

闲聊

奥迪就是买灯送车,奥迪灯太亮了。

工厂创建对象

image-20211002011215730

image-20211002011311721

这是返回对象类型。

image-20211002011331750

这是判断对象,是否是单例,默认为false。

配置文件当中怎么配置工厂bean

在配置文件当中,我不需要创建car的对象,我们把car对象的创建,交给了工厂bean。

image-20211002011534000

创建一个测试类

image-20211002011815608

这个结果,是我想要的结果,但是有点问题,我们getBean的时候,写的是factory,factory代表的是工厂bean。

按照之前的普通bean的经验,通过getBean获得的是哪个id的bean,一定是bean的class对应的对象。

我们现在拿到的,不是工厂bean,我们获取的是工厂bean创建的bean对象。

这就是我们spring当中,创建的第二种bean对象,叫做工厂bean。

虽然我们bean的class是工厂的全限定名,最终获取的bean,是工厂创建的对象。也就是工厂当中getObject方法返回的对象。

总结

在这里插入图片描述

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值