Spring
1.Spring是什么
Sprig是分层的Java SE/EE应用full-stack(全栈)轻量级开源框架,以IoC(Inverse Of Control:控制反转)和AOP(面向切面编程)为内核。
提供展现层SpringMVC和持久层Spring I+JDBCTemplate以及业务层事务管理等众多企业级应用技术,还可以整合开源世界众多著名的第三方框架和类库,逐渐成为使用最多的Java EE企业应用开源框架。
Spring是包含众多工具方法的IoC容器。
所接触到的容器有:
List/Map—>数据存储容器;
Tomcat------>Web容器。
2.Spring的优势
1.方便解耦,简化开发。通过Spring提供的IoC容器,可以将对象间的依赖关系交由Spring进行控制,避免硬编码所造成的过度耦合。用户不需要再为了单例模式类、属性文件解析等这些很底层的需求编写代码,可以更专注于上层的应用。
2.AOP编程的支持:通过Spring的AOP功能,方便进行面向切面编程,许多不容易用传统OOP实现的功能可以通过AOP轻松实现。
3.声明式事务的支持:通过声明式方式灵活的进行事务管理,提高开发效率和质量。
4.方便程序的测试:可以用非容器依赖的编程方式进行几乎所有的测试工作。
5.方便集成各种优秀框架:Spring对各种优秀的框架(Struts、Hibernate、Hession、Quartz等)的支持。
6.降低JavaEE API的使用难度:Spring对JavaEE API(如JDBC、JAVAMail、远程调用等)进行了薄薄的封装层,使这些API的使用难度大为降低。
7.Java源码是经典的学习范例
3.Spring程序开发步骤
1.导入Spring开发的基本包坐标;
2.编写Dao接口和实现类;
3.创建Spring核心配置文件;
4.在Spring配置文件中配置UserDaoImpl;
5.使用Spring的API获得Bean示例。
4.Spring配置文件
1.Bean标签基本配置
基本属性:
id:Bean实例在Spring容器中的唯一标识;
class:Bean的全限定名称。
2.Bean标签范围配置:scope:指对象的作用范围
singleton:默认值,单例的;
prototype:多例的;
request:Web项目中,Spring创建一个Bean对象,将对象存入到request域中;
session:Web项目中,Spring创建一个Bean对象,将对象存入到session域中;
global session:Web项目中,应用在Portlet环境,如果没有Protlet环境,那么globalSession相当于session.
5.SpringBoot框架
1.为什么要学习框架?
因为框架更简单易用、简单且高效
2.SpringBoot VS servlet:
无需配置tomcat,点击运行,就可以运行项目,Spring Boot内置了Web容器(可以直接运行)
快速添加外部jar包
快速发布项目(使用java -jar方式可以发布)
对象自动装配
6.SpringBoot VS Servlet
SpringBoot相对比Servlet的优点总结:
1.添加外部jar更容易,不易出错;
2.调试项目更加方便,无需配置Tomcat;
3.发布项目更加方便,无需配置Tomcat;
4.添加路由更加方便,无需每个访问地址都添加一个类。
7.什么是IoC容器?
一、Spring 是一个IoC容器
IoC:Inversion of Control:“控制反转”,Spring是一个"控制反转"的容器。
在之前的开发中,由程序员来管理一个程序(一个一个类)的生命周期;
控制反转是指:将程序的生命周期交给Spring框架来管理。
二、IoC容器的特点:
1.创建类发生了反转(比如:车->框架->底部->轮胎,控制反转后:轮胎->底部->框架->车);
2.底层调用类发生改变之后,IoC模式整个调用链上的代码是不需要修改的,实现了类与引用类的解耦,但是,传统开发方式是不行的。
3.如果要使用依赖类,需要自己创建类管理类的生命周期,IoC无需自己管理对象的生命周期。
三、Spring是一个IoC容器,所具备的两个基础功能是:
1.将对象存入到容器;
2.从容器中取出对象。
Spring最核心的功能是:学会如何将对象存入到Spring当中,再从Spring中获取对象的过程。
Spring是一个IoC容器,对象的创建和销毁都交给Spring来管理,本身又具备了存储对象和获取对象的能力。
8.DI
一、DI是什么?
Dependency Injection:“依赖注入”:在创建当前类的时候,动态的将当前类的依赖对象注入进来的过程叫做DI(依赖注入)。
二、IoC VS DI
IoC是控制反转,是一种设计思想。
DI是实现手段。
9. Spring项目的创建和使用
1.创建Spring项目;
2.将对象存储到Spring框架中;
3.将对象从Spring框架中读出来。
1.创建Spring项目
1.1基于Maven创建Spring项目
1.2检查是否存在setting.xml文件并且在这个文件当中是否有国内源。
1.3添加Spring框架支持:
在pom.xml当中添加Spring框架的支持
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>5.2.3.RELEASE</version>
</dependency>
</dependencies>
1.3创建一个启动类(目的是:为了测试Spring的核心功能,存对象和取对象)
2.将对象存储到Spring
2.1先创建一个业务对象。
2.2将对象存储到Spring框架(声明式的创建)
<?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">
</beans>
在resources下面创建一个spring-config.xml,在这个里面加入上面一段代码
3.获取并使用Bean对象:
3.1得到Spring上下文对象,因为对象都交给Spring管理了,所以获取对象要从Spring中获取,那么就先得获得Spring的上下文;
3.2通过Spring上下文,获取某一个指定的Bean对象;
3.3使用Bean对象。
获取bean对象的三种方式
1.通过id获取bean对象(需要类型转换)
2.通过类型来获取bean对象
缺点:对于多个对象的同一种类型的bean,会报错。
优点:无需类型转换
3.通过 id+类型 的方式来获取bean对象
优点:无需类型转换,对于多个对象指向一个类(类型)的情况,不会报错。
10.获取Spring上下文
Spring上下文对象可以使用:ApplicationContext,也可以使用BeanFactory
11.BeanFactory VS Application(*)
BeanFactory VS Application
1.二者来自的jar包不同
2.继承关系和功能方面来说:Spring容器有两个顶级的接口:BeanFactory和ApplicationContext,其中,BeanFactory提供了基础的访问容器的能力,而ApplicationContext属于BeanFactory的子类,它除了继承BeanFactory的所有功能之外,还具有独特的国际化支持、资源访问支持、以及事件传播等方面的支持。
3.从性能方面来说:ApplicationContext是一次性加载并初始化所有的Bean对象,而BeanFactory是需要哪个才去加载哪个,因此更轻量些。
4.ClassPathXmlApplicationContext属于ApplicationContext的子类,拥有ApplicationContext的所有功能,是通过xml的配置来获取所有的Bean容器的。
12. Spring更简单的读取和存储对象
在spring中想要更简单的存储和读取对象的核心是使用注解
因为idea上面没有配置maven,每一次创建的时候都需要在setting.xml当中去检查
1.配置spring.xml设置spring存入对象的根路径。
目的:让Spring项目启动之后,能够在根路径下的所有类中扫描并将标识为需要存储到Spring中的对象存储到Spring中 。
2.使用注解,将Bean对象存储到Spring框架当中
注解分类:
1.类注解:@Controller【控制器】、@Service【业务逻辑层】、@Repository【数据持久类】、@Component、@Configuration
2.方法注解:@Bean
@Configuration:系统配置信息;
@Controller:业务逻辑层(数据校验);
@Service:业务逻辑层(数据组装);
@Repository:数据库的交互,表的CRUD操作;
@Component:组件(公共组件).
3.更简单的存储对象到Spring的实现步骤:
1.先创建一个Maven
2.添加Spring的核心包
3.配置Spring的xml文件,配置Spring组件的扫描路径(所有需要存储在Spring中的对象都需要放在此目录下)
4.创建一个普通类,添加main,作用:方便进行调试
5.使用注解实现对象存储在Spring框架
4.使用Controller注解
1.
2.
5.使用Bean注解
Bean注解在方法上面,但是spring会扫描不上,spring默认情况下,是类级别的扫描,所以,在使用方法Bean注解的时候,需要在类上面加上一个类注解(通常情况下,会使用@Component)
1.
2.
3.
6.重命名Bean
Bean重命名可以有多个别名,但是,当指定别名之后,使用方法名就取不到对象了。
1.
2.
7.从Spring中获取对象的手段:
1.属性注入(属性注册)UserController–>UserService
2.Setter注入;
3.构造方法注入
(1)属性注入
1.从Spring框架中获取到UserController对象
2.通过属性注入的方式,从Spring框架中获取到Service对象
3.
(2)Setter注入
第一步:添加对象
第二步:创建setter方法
第三步:在setter方法上面添加@Autowired(这个是不可以省略的)
方法测试:
1.通过获取对象上下文的方式,获取到UserController2的对象
2.在UserController2类当中,通过setter注入,获取到UserService的对象
3.
(3)构造方法注入
第一步:添加对象
第二步:写构造方法
第三步:在构造方法上面加上@Autowired(当只有一个构造方法的时候,可以忽略@Autowired,如果有两个构造方法的时候,就不可以省略@Autowired)
方法测试:
1.通过上下文的方式,从Spring框架中获取到UserController3的对象
2.在UserController3类当中,通过构造方法注入,从spring框架中获取到UserService的对象
3.
4.结果展示
三种注入的优缺点
1.属性注入
优点:是简洁,使用方便。
缺点:只能用于IoC容器,如果非IoC容器使用,会在使用中出现空指针异常。
2.构造方法注入式Spring推荐的注入方式。
缺点:如果有多个注入,会显得比较臃肿,
优点:通用性,在使用之前保证注入的类不为空。
3.Setter注入:
Setter方式是Spring前期版本推荐方式,但是通用性不如构造方法。
13.@Resource
在进行类注入的时候,除了可以使用@Autowired关键字之外,还可以使用@Resource进行注入。
(1)属性注入
(2)setter注入
(3)构造方法注入(用@Resource是不可以的,会报错)
@Autowired和@Resource有什么区别?
1.出身不同:
@Autowired来自于Spring框架,而@Resource来自JDK;
2.作用范围不同:
@Autowired可以进行属性注入、setter注入、构造器注入;
@Resource可以进行属性注入、setter注入;
3.功能不同:
@Resource可以支持更多的属性;比如,可以配合name属性使用,从而完成对象的别名注入
@Autowired可以支持的属性比较少。
解决同一类型多个Bean的报错
1.使用@Resource(name=“”)
2.使用@Qualifier(“”)
14.Bean的作用域和生命周期
1.Bean的作用域
Bean的作用域是指:Bean在Spring整个框架中的某种行为模式。
比如,singleton单例作用域,表示Bean在整个Spring中只有一份,是全局共享的,当其他人修改这个值之后,另一个人再读取这个值就是修改后的值。
2.Bean的6种作用域
Spring容器在初始化一个Bean实例的时候,同时会指定该实例的作用域。Spring有6种作用域。
1.singleton:单例作用域;
2.prototype:原型作用域;
3.request:请求作用域;
4.session:会话作用域;
5.application:全局作用域;
6.websocket:Http WebSocket作用域.
后四种状态是Spring MVC中的值,在普通Spring项目中只有前两种。
3.Singleton
描述:该作用域下的Bean在IoC容器中只存在一个实例,获取Bean(通过applicationContext.getBean)以及装配Bean(通过@Autowired注入)都是同一个对象实例
场景:通常无状态的Bean使用该作用域。无状态表示Bean对象属性状态不需要更新。
Spring默认选择该作用域。
1.
2.
3.
4.结果
5.通过结果,有一个结论:默认的Bean的作用域是singleton,当一个人修改某个数据的时候,其他人的这个数据都是修改后的数据。一个人修改,全部的都会受到影响。
4.prototype
描述:每次对该作用域下的Bean的请求都会创建新的实例:获取Bean(通过applicationContext.getBean)以及装配Bean(通过@Autowired注入)都是新的对象实例。(在加载的时候,只创建一次)
场景:通常有状态的Bean使用该作用域。
限定SpringMVC中使用
5.request
描述:每次http请求会创建新的Bean实例,(每次都会创建);
场景:一次http的请求和响应的共享Bean;
6.session
描述:在一个http session中,定义一个Bean实例;
场景:用户会话的共享Bean,比如:记录一个用户的登录信息
7.application
描述:在一个http servlet Context中,定义一个Bean实例;
场景:Web应用上下文信息,比如,记录一个应用的共享信息
8.websocket
描述:在一个http websocket的生命周期中,定义一个Bean实例;
场景:WebSocket的每次会话中,保存了一个Map结构的头信息,将用来包裹客户端消息头。第一次初始化后,直到WebSocket结束都是同一个Bean
限定Spring WebSocket中使用。
9.单例作用域 VS 全局作用域
singleton是Spring Core的作用域,application是Spring Web的作用域;
singleton作用于IoC容器,application作用于Servlet容器.
10.如何设置作用域?
1.直接设置值:@Scope(“prototype”)
2.使用枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Scope可以适用于方法注解也可以适用于类注解
3.设置作用域
结果展示:
结果分析,将作用域设置为@Scope(“prototype”),当一个数据被修改之后,其他人的数据是不会发生改变的。
15.Bean执行流程
1.启动容器
2.加载配置文件(类加载路径下的spring.xml),根据配置完成Bean初始化。
3.扫描com.model包下面的Spring注解:
@Controller、@Service、@Component、@Resposity、@Configuration,注册Bean对象到容器中
如果Bean对象需要其他Bean对象作为属性,可以使用@Autowired、@Resource,装配Bean的属性。
Spring Bean大的执行流程:
Spring Bean大的执行流程:
1.启动Spring容器;
2.加载Spring配置文件;
3.加载配置文件中的bean,或者是根据配置文件中的组件(Bean)根路径,进行Bean对象的扫描,5大类注解,如果有注解直接加载。
4.加载的对象存储到Spring。
5.其他需要使用Bean对象的地方就可以直接获取并使用。
6.执行完之后,执行销毁操作。
Bean的生命周期:
生命周期:指的是一个对象从诞生到销毁的整个生命过程,这个过程叫做一个对象的生命周期.
Bean生命周期分为:
1.实例化Bean:给Bean对象分配内存空间。
2.设置属性(Bean注入和装配)
3.Bean初始化:
a.实现了各种Aware通知的方法,如,BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法;
b.执行BeanPostProcessor初始化前置方法;
c.执行@PostConstruct初始化方法,依赖注入操作之后被执行;
d.执行指定的init-method方法;
f.执行BeanPostProcessor初始化
4.使用Bean;
5.销毁Bean。销毁容器的各种方法,
@PreDestroy:销毁前方法
DisposableBean接口方法:接口如果有实现方法
destroy-method:销毁前的执行方法
1.
2.
3.
4.结果展示: