1、spring全家桶,由一堆框架构成,简称全家桶。
2、spring全家桶构成
起源书:J2EE Development without EJB
spring全家桶:
全家桶中比较常用的几个框架如下:==================================
springframework:框架的春天,通常说spring就是指的springframework
springboot:一键启动
springcloud:分布式开发
springframework构成如下图:
3、springframework核心概念
IOC:控制反转。
从自己new对象,变成IOC容器给你提供对象,IOC容器管理对象的创建和销毁。IOC容器创建的对象先拿在它自己手里,叫做bean。IOC容器就是springframework的core container,程序一启动,这个容器就会被创建。
那么这个容器怎么知道哪些对象需要由它创建和销毁呢?答案是通过注解或者XML配置指定。见第9条。
如果对象A通过注解告诉了IOC容器交给它创建,A中又依赖了其他对象B,IOC又如何帮我们创建呢,比如servlet中依赖了service,service中依赖了dao?答案是通过配置让IOC容器能自动识别,将B自动纳入容器管理创建和销毁。见第15条。
对象A交给IOC容器创建后,要使用A的时候怎么从IOC容器中获取呢?答案是:先通过接口拿到IOC容器,调用接口方法获取IOC容器中管理的对象。
DI:依赖注入。在容器中已经存在了一堆bean,容器会自动在容器中将有依赖关系的bean进行关系绑定。这个依赖关系需要我们在配置文件中指定。见第15条。
4、简单实现IOC:XML配置
需求分析:将BookServiceImpl和BookDaoImpl交给Spring管理,并从容器中获取对应的bean对象进行方法调用。
1.创建Maven的java项目
2.pom.xml添加Spring的依赖jar包,context依赖会自动导入IOC容器所需的四个依赖包,当然也可以自己挨个导入。。
3 .创建BookService,BookServiceImpl,BookDao和BookDaoImpl四个类
4.resources下添加spring配置文件,并完成bean的配置
5.使用Spring提供的接口完成IOC容器的创建
6.从容器中获取对象进行方法调用
5、简单实现DI
上面实现IOC的例子中,dao和service分别交给了IOC容器管理,IOC容器中存着这两个对象的bean,我们可以从IOC容器中取出dao和service对应的bean来使用,但是我们可以看到service中依然要我们自己new dao对象才行,那能否这里这个dao对象也由IOC容器给我们呢?spring提供了这样的功能。首先要将两个对象都交给IOC容器创建,然后在配置文件中绑定他们的关系,然后在service中一定要写一个set方法来,IOC容器会自动调用那个set方法来将它管理的dao对象给serveice。
6、bean的别名,通过name属性配置,用处不大
7、控制获取到的bean是不是单例的,spring默认是单例的。通过scope配置非单例。在web项目中scope还可以控制对方存放在 哪个域对象中。
8、哪些适合单例,即适合交给spring管理?哪些不适合交给spring管理?
- 为什么bean默认为单例?
- bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
- bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高
- bean在容器中是单例的,会不会产生线程安全问题?
- 如果对象是有状态对象,即该对象有成员变量可以用来存储数据的,
- 因为所有请求线程共用一个bean对象,所以会存在线程安全问题。
- 如果对象是无状态对象,即该对象没有成员变量没有进行数据存储的,
- 因方法中的局部变量在方法调用完成后会被销毁,所以不会存在线程安全问题。
- 哪些bean对象适合交给容器进行管理?
- 表现层对象
- 业务层对象
- 数据层对象
- 工具对象
- 哪些bean对象不适合交给容器进行管理?
- 封装实例的域对象,因为会引发线程安全问题,所以不适合。
9、bean的实例化方式四种:bean就是对象,bean的实例化=bean的创建。原理:反射。
方式一:通过无参数构造方法创建。有有参构造的话必须要有无参构造。
方式二:静态工厂实例化,属性factory-method。极少使用,因为spring就是个大工厂了,我们没必要创建自己的工厂。
方式三:实例工厂。
方式三变种:实现springwork提供的FactoryBean接口。将我们写的工厂也放到IOC容器中管理!与其他框架连接!
//FactoryBean创建对象
public class UserDaoFactoryBean implements FactoryBean {
//代替原始实例工厂中创建对象的方法
public UserDao getObject() throws Exception {//产出的对象
return new UserDaoImpl();
}
public Class getObjectType() {//产出对象的类型
return UserDao.class;
}
public boolean isSingleton() {//指定是否
return false;
}
}
10、spring报错,从下往上看
11、如何进行bean的初始化?
init-method属性
12、如何才能执行bean的销毁?
destory-method属性。
暴力关容器ctx.close()。
注册钩子关闭容器 ctx.registerShutDownHook()。
13、bean的生命周期
bean生命周期小结
(1)关于Spring中对bean生命周期控制提供了两种方式:
- 在配置文件中的bean标签中添加init-method和destroy-method属性
- 类实现InitializingBean与DisposableBean接口,这种方式了解下即可。
(2)对于bean的生命周期控制在bean的整个生命周期中所处的位置如下:
- 初始化容器
- 1.创建对象(内存分配)
- 2.执行构造方法
- 3.执行属性注入(set操作)
- ==4.执行bean初始化方法==
- 使用bean
- 1.执行业务操作
- 关闭/销毁容器
- ==1.执行bean销毁方法==
(3)关闭容器的两种方式:
- ConfigurableApplicationContext是ApplicationContext的子类
- close()方法
- registerShutdownHook()方法
14、spring允许有多个厂
15、DI依赖注入方式4种(简单数据类型、引用数据类型)
标准书写有以下两种,耦合较紧:
setter注入:类中写setter,配置文件bean标签中使用property标签。属性ref和value,一个使用引用数据类型,一个基本数据类型。
构造器注入:类中写带参构造器,配置文件bean标签中使用constructor-arg标签。属性ref和value,同上。
上面已经完成了构造函数注入的基本使用,但是会存在一些问题:
当构造函数中方法的参数名发生变化后,配置文件中的 name 属性也需要跟着变 这两块存在紧耦合,具体该如何解决 ? 在解决这个问题之前,需要提前说明的是,这个参数名发生变化的情况并不多,所以上面的还是比较 主流的配置方式。标准写法构造器注入的另一种书写方式1,松耦合,但参数类型一样时无法解决:
不用name属性,用type属性区分给的参数位置
标准写法构造器注入的另一种书写方式2,松耦合:
不用name属性,用index属性区分参数位置
16、DI依赖注入方式的选择
两种参数的注入方式,具体我们该如何选择呢?
- 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
-
- 强制依赖指对象在创建的过程中必须要注入指定的参数
- 可选依赖使用setter注入进行,灵活性强
-
- 可选依赖指对象在创建过程中注入的参数可有可无
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 实际开发过程中还要根据实际情况分析,如果受控对象没有提供setter方法就必须使用构造器注入
- ==自己开发的模块推荐使用setter注入==
17、上述方式都需要我们自己在配置文件中配置哪些对象需要注入,还要在类中写好构造器或者setter。spring提供了简化上述配置文件书写的方法,但没简化类的书写,且只能用于引用类型的依赖注入,即自动装配注入:
(1)、注入唯一的bean,可以用属性autowire=byType。推荐使用。
(2)、不唯一的bean,可以用autowire=byName。耦合较大,少用。
18、自动装配优先级低于setter注入和构造器注入。
19、以上实现了基本数据类型和引用数据类型的注入,但集合的注入有特殊的注入方法,极少用。
100 200 300
888 555 boxuegu chuanzhihui itcast 1 boxuegu boxuegu china henan kaifeng



