Spring Fmework 系统架构图
Spring Framework学习线路
一、核心概念
首先对代码而言:
就上面的问题如果换成新的实现NoolDaoImpl2后,然后业务层new NoolDaoImpl2();后,说明原来上线的项目的代码动了,那么我们是不是就要重新测试、重新部署、重新发布我们新修改的代码项目(这些工作都要做一遍,项目产品才能上线)
所以在代码书写现状上出现了下列问题:
1.1、IoC控制反转核心概念:
细节1:IoC容器中两个bean之间如果有依赖的关系,那么在Ioc容器当中也建立好了两者之间的依赖关系,如上述左边代码业务层service需要依赖dao对象运行,在Ioc容器中就已经将二者之间的依赖建立好了,称为DI依赖注入
细节2:IoC容器可以提供创建任何对象
上述做法的最终目标:就是对代码之间充分解耦
二、Ioc入门实现
2.1未使用Ioc容器时:
主动new产生对象 开始执行:
结果:
2.2、使用Ioc容器:(注意:下面4个步骤,一个也不能少)
第一步: 先导入spring的坐标:
第二步: 在该文件中配置bean:
从第四步可以看出,使用Ioc容器后,就不用内部再new对象然后调用方法了,由外部Ioc容器创建管理对象(bean),起到了解耦合度的作用
三、DI入门实现
因为bean与bean之间有依赖的作用(演示的也就是说:需要主动new 对象)所以会使耦合度增高,为了降低耦合度,Ioc容器顺便也把bean与bean之间有依赖的事情给处理了
Ioc容器处理bean与bean之间的关系演示如下:(降低耦合度)
第一步:先把new另外一个bean管理的对象删除掉(把右半截new的部分删除掉即可,其余的左边保留)
第二步:设置一个set方法
第三步:处理Ioc容器中 bean之间的依赖关系
四、bean配置
4.1、bean别名配置
4.2、bean作用范围配置
用非单例进行设置后:(就不再是同一个bean内存地址了,相当于开辟了两个bean的内存地址)
五、bean实例化
5.1、bean实例化 ---- 构造方法
注意:无参数构造方法,默认情况下就存在的,和javase里面的一样,不写就代表着进入的是无参数构造方法
代码演示如下:
BookDaoImpl:
调用获取的Ioc容器中被管理的对象中的save()方法:(会发现先实例化了该bean方法中的无参数构造方法)
当无参数构造方法,写成有参数构造方法的时候,就会报错:
5.2、bean实例化----工厂(先不看)
六、bean的生命周期控制
调用一个对象中的某个方法时:该对象中有无参数构造方法的时候,最先执行无参数构造方法,然后有起始生命周期的方法的时候,再执行起始生命周期的方法,然后再执行调用的某个方法,最后调用的是销毁周期的方法
注意1:要想执行生命销毁周期的方法,必须要关闭勾子并且保证该IOC容器是单例形式
6.1、第一种生命周期的控制方式:xml文件起始销毁属性配置生命周期
结果演示:
思考:为什么销毁的方法不执行呢?
因为其实我们的程序是运行在java虚拟机中的,当程序执行到save()方法的时候,虚拟机就会退出了,所以来不及执行destroy()销毁的方法。
解决方法1:调用关闭勾子方法
6.2、第二种生命周期的控制方式:spring接口的方式
InitializingBean:初始化bean (也就是说:生命起始周期)
DisposableBean:销毁bean (也就是说:生命销毁周期)
七、setter注入
7.1 setter注入----引用类型 (也就是说new对象的形式)
7.1.1、当代码中只有一个依赖关系的时候演示如下:(也就是说,假设只有一个private BookDao bookDao = new BookDaoImpl();的时候)
我们前面讲的代码之间有依赖关系的时候,Ioc容器会帮我们处理好两个bean(对象)之间的依赖关系,这种方式称为:DI依赖注入
AppForDISet:
演示如下:
BookServiceImpl:
我们从运行结果可以看出,虽然我们是最后调用的BookDao对象中的save()方法的,但是该BookDaoImpl方法当中有无参数构造方法,所以同样会先执行无参数构造方法的
该依赖对象:BookDaoImpl:
运行结果如下所示:
7.1.2、 当代码中有两个或者多个依赖关系的时候:(也就是说有private BookDao bookDao = new BookDaoImpl();也有private UserDao userDao =new UserDaoImpl();的时候)
AppForDISet:
BookServiceImpl:
UserDaoImpl:
BookDaoImpl:
运行结果如下所示:(同样被依赖的对象有无参数构造方法的时候,也是先执行无参数构造方法,然后再执行save()方法 )
7.2、setter注入----简单类型
AppForDISet:
BookServiceImpl:
BookDaoImpl:
在spring的xml文件当中进行给BookDaoImpl对象中的属性赋值处理:
注意:这个name属性所对应的值,相当于被依赖对象 BookDaoImpl 中set方法中除set单词的方法名 如:setConnectionNum 那么name就应该和ConnectionNum对应
运行结果如下所示:
八、构造器注入
构造器注入方式和setter注入方式原理其实都是一样的,(两个用哪个方式都可以)
8.1、引用类型中当只有一个依赖对象的时候代码演示如下:
BookServiceImpl:(这里要注意:spring的xml文件当中的构造器方式处理依赖关系的name属性当中的值,对应的是该对象当中的构造器方法当中的参数值)
spring的xml文件:
BookDaoImpl:
运行结果如下所示:
8.2、引用类型中当有两个或者多个依赖对象的时候代码演示如下:
spring的xml文件:
运行结果如下所示:
8.3、简单类型中使用构造器方式注入的代码演示
BookDaoImpl:
BookServiceImpl:
AppForDIConstructor:
运行结果如下所示:
小问题:
我们会发现,构造器注入的方式会有一个弊端,也就是说,当我们构造器方法的参数名改变后,我们xml文件当中的配置也要跟着改变:
因此有一个解决的办法,就是使用index标的形式: