第一部分:Spring框架概述、Spring、IOC、单例、多例、依赖注入
所谓的框架其实就是程序的架子,在这个程序的架子中,搭建起程序的基本骨架,针对程序的通用问题给出便捷的解决方案,可以使开发人员基于框架快速开发具体的应用程序。
早期的框架: SSH
Struts2(不安全)
Spring
Hibernate(性能低、复杂)
现在的框架: SSM
SpringMVC
Spring
MyBatis
Spring是一个在业务层(Model层(M层) Dao层)使用的开源框架,可以整合许多其他的框架进行开发工作。
Spring的主要技术:IOC(DI依赖注入)和AOP
IOC(DI):控制反转(依赖注入)
IOC用来完成一个对象的创建和销毁
IOC主要是用来解耦合
AOP:面向切面编程
也是为了解耦合,层与层之间加入切面代码
step1:下载Spring
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gUgTxpbW-1621820271227)(file:///C:/Users/刘忠祥/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg)]
docs:文档
libs:jar包
schema:约束
step2:新建一个普通的java项目
step3:导入开发Spring需要的jar包(开发IOC至少需要7个jar包)
step4:Spring开发需要一个专门的配置文件,配置文件的文件名和位置是任意的,一般定义在src目录下, 文件名一般叫applicationContext.xml
step5:Spring的配置文件不知道怎么写,需要引入Spring约束(schema)
step6:制定xml模板
IOC:控制反转,即将对象的创建的权利以及对象的生命周期的管理过程交给Spring框架来处理,从此在开发过程中不再需要关注对象的创建和生命周期的管理,而是在需要时由Spring框架来提供,这个由Spring框架管理对象创建和生命周期的机制称之为控制反转
DI:依赖注入。在创建对象的过程中,Spring可以依据配置对象的属性进行设置,这个过程称之为依赖注入
在初始化一个Spring容器时,Spring会解析指定的xml文件,当解析到其中的标签时,会根据该标签的class属性指定的类的全路径名,通过反射机制反射该类的对象,将该对象存入内置的Map中管理
结论:
(1) 默认情况下,多次获得同一个id的bean,得到的是同一个对象;
(2) 即使是同一个类,如果配置过多个标签具有不同得到id,那么通过id获得的对象是不同的对象
(3) 在配置文件中如果配置多个标签同时具有相同的id,则会报错
(1) 通过bean的id来获取
(2) 通过class来获取对象
(3) 通过别名来获取对象
\1. 通过类的无参构造方法创建对象
这种情况下,Spring创建对象时要求类必须有无参构造,否则的话无法获取创建对象并报异常。
\2. 通过静态工厂创建对象
如果类因为各种情况导致类无法提供无参构造方法,此时Spring容器就无法通过无参构造创建类,那么可以使用静态工厂的方式创建类。即:把创建对象的过程封装在静态工厂中(类)
\3. 通过实例工厂创建对象
当类无法通过无参构造创建时,可以使用实例工厂来创建类。解决思路和静态工厂相似,只不过实例工厂提供的方法不是静态方法
\4. 通过Spring工厂创建对象
Spring内置了工厂接口(FactoryBean接口),也可以通过实现这个接口来开发Spring工厂,通过这个工厂来创建对象
Spring容器管理的bean在默认情况下是单例的,也就是说一个bean只会创建一个对象,存放在内置的map中,之后无论获取多少次该bean,都返回同一个对象
Spring默认采用单例模式,减少了对象的创建,从而减少了内存的消耗。但是实际开发中存在多例的需求,Spring也可以设置bean为多例模式
总结:
(1) Bean在单例模式下的生命周期
bean在单例模式下,Spring容器启动时解析xml文件发现bean标签,直接创建bean对象,然后存入到内部的map中保存,此后无论调用多少次getBean()获取该bean,都是从map中取出来该对象,一直都是一个对象。此对象一直被Spring容器持有,直到Spring销毁时对象也销毁。
(2) Bean在多例模式下的生命周期
bean在多例模式下,Spring容器启动时解析xml文件发现bean标签,只是将bean进行管理,并不会创建****bean,此后每次使用getBean()获取bean时,Spring会重新创建该对象并返回,每次都是一个新对象。
这个时候Spring容器不会持有它,什么时候销毁取决于使用该对象的用户自己决定。
Spring默认会在容器初始化的过程中解析xml文件,并将单例的bean创建并保存到map中,这样的机制在bean的数量比较少的时候问题不大,一旦bean的数量非常多的时候,Spring需要在启动的过程中花费大量的时间来创建bean、花费大量的空间存储bean,但是这些bean可能很久都用不上,这种在启动时时间和空间上的浪费就显得非常不值得。
Spring提供了懒加载机制来解决这个问题,所谓的懒加载机制就是可以指定bean不在Spring容器启动的时候创建,而是在后续第一次用到的时候才创建,从而减轻在Spring容器启动过程中对时间和空间的消耗。
懒加载机制只对单例模式下的bean起作用,对于多例模式下的bean设置懒加载没有任何意义
lazy-init=“true” bean就进行懒加载
lazy-init=“false” 不懒加载,默认
lazy-init=“default” 是否懒加载取决于标签中的设置
总结:
(1) 单例模式下未设置懒加载(没有驾照,先买车放着,以后想开车再开)
Spring容器初始化的时候就会先创建bean,等以后getBean()的时候再用,这就造成了时间和空间的浪费。
(2) 单例模式下设置懒加载(先不买车,驾照到手了就买,以后想开就开)
Spring容器初始化的时候不会创建bean,等第一次调用getBean()的时候创建bean,并放入map中存储,等再次调用getBean()的时候从 map中取就可以。
即:车就一辆,创建的bean就创建一次
(3) 多例模式 – 不考虑懒加载(每次想开车就买新车)
Spring容器初始化的时候不会创建bean,每一次调用getBean()的时候创建一个新的bean。
当多个bean都需要设置懒加载的情况:
在标签中设置:default-lazy-init=“true”
Spring容器初始化的时候会做一下创建、连接的操作
init-method="" – 在Spring初始化的时候执行哪个方法
Spring容器的销毁做一些关闭、资源释放等工作
destroy-method="" – 在Spring销毁的时候执行哪个方法
在创建对象的过程中,Spring可以设置对象的属性,这个过程就做依赖注入,也叫DI
原来的做法:
Person p=new Person();
p.setage();
现在Spring可以通过IOC管理Person对象,可以通过DI设置Person类中的属性
如果Hero类中包含了其他的JavaBean类,需要分别引入
以上两行配置是引入bean,可以省略,使用自动装配
自动装配使用的情况:引入的bean特别多的情况下
autowire=“byName”
Spring会自动根据JavaBean类的属性寻找标签对应的id来进行属性的依赖注入
要求要注入的JavaBean类中的属性和**标签对应的id****值对应一致**
autowire=“byType”
Spring会自动根据JavaBean类的属性的类型(private Dog dog),去配置文件中寻找标签配置的class的值(com.ldu.domain.Dog)
要求要依赖注入的JavaBea