SSM原理总结

一、Spring

1.servlet由来

在讲spring之前,需要讲一些基础知识,Web服务器使用HTTP协议来传输数据。用户在浏览器(客户端,client)中输入一个URL,此时客户端向服务器发送HTTP请求,服务器处理HTTP请求发送响应(通常是一个网页)至客户端。所以服务器里需要一个程序处理HTTP请求,这个程序需要识别正确和错误的HTTP请求;识别正确和错误的HTTP头;复用TCP连接;复用线程;IO异常处理等等, 这些基础工作需要耗费大量的时间,并且经过长期测试才能稳定运行。如果我们只需要输出一个简单的HTML页面,就不得不编写上千行底层代码,那就根本无法做到高效而可靠地开发。
所以在JavaEE平台上,处理TCP连接,解析HTTP协议这些底层工作统统扔给现成的Web服务器去做,我们只需要把自己的应用程序跑在Web服务器上。为了实现这一目的,JavaEE提供了Servlet API,我们使用Servlet API编写自己的Servlet来处理HTTP请求,Web服务器实现Servlet API接口,实现底层功能:

在这里插入图片描述

2.Spring由来

在以前主流框架是EJB,但是他有两个缺陷,一个是运行环境苛刻,Javaweb开发需要servlet,但是EJB需要运行在EJB容器中,但是Tomcat的核心是servlet引擎,没有EJB容器,其他服务器不开源且需要收费,第二个是代码移植性差.EJB代码运行在各种服务器中要实现每种服务器的接口,因此移植性差,所以称它是重量型框架在这里插入图片描述
为了解决这两个问题,出现了spring框架,它是一个轻量级的JavaEE解决方案,整合了众多优秀的设计模式, 为了解决这两个问题,出现了spring框架,它是一个轻量级的JavaEE解决方案,整合了众多优秀的设计模式,为什么是轻量级的它对于运行环境是没有额外要求的,不管是开源的服务器还是收费的服务器都可以。
• 代码移植性高,不需要实现额外的接口
为什么是Javaee解决方案呢
Java开发分为三层,controller层调用service层接口处理客户端请求,service层调用dao层实现业务逻辑,dao层与数据库交互,有strus2框架,mybatis框架都是只专注于一层的问题,而spring可以有的springmvc处理controller层问题,spring的AOP,IOC模块处理service层问题,与与各持久层框架整合解决DAO问题
在这里插入图片描述

3.工厂模式

Spring整合了许多设计模式,其中比较核心的是工厂模式,工厂模式的概念就是通过工厂类创建对象.以前创建对象是直接new,但是这样会有耦合,看这张图,userService是一个借口,userserviceimpl是它的实现类,这样设计是为了屏蔽业务实现的差异,但是如果后续实现类改变了,则这个控制器代码也要改变,这样就是说代码存在耦合,而工厂模式可以解耦合,在java里面创建对象的方式有两种,一个是直接调用构造方法new一个对象,一个是通过反射的方式创建对象,这个方式可以解耦合,他有两步操作,第一步获取类对象,看这行代码Class clazz = Class.forName(“全路径类名”)第二部通过newINstance方法获取它的对象(返回的是object类型,反射是要产生异常的所以要加try catch,后续全路径类名可能会改变,这里也有耦合,我们通过配置文件来处理,这个文件有一个叫properties的集合存储properties文件内容, properties是一个特殊的map集合,key是string,value也必须是string类型,用getProperty方法得到全路径类名,这个编码看着麻烦但是是spring所做的工作,不用我们自己写,这里了解原理是为了提供调试代码的思路在这里插入图片描述

4.程序开发

实际开发过程中,创建对象是用三步的,首先创建类(要在在Java目录专门用于放置代码文件)第二步配置文件的配置, 配置文件变为spring的配置文件applicationContext.xml ,例如在配置文件中添加person的bean。最后通过springspring提供的工厂类ApplicationContext ,获得对象
工厂类ApplicationContext 有两个子类,一个是非web开发的ClassPathXmlApplicationContext,一个是基于web开发的XmlWebApplicationContext
• 需要注意的是,工厂类是重量级资源, ApplicationContext工厂对象占用大量内存。所以通常情况不会频繁的创建对象:一个应用只创建一个工厂对象。并且ApplicationContext工厂:一定是线程安全的(因为要满足多线程并发访问)
在这里插入图片描述

5.spring工厂模式

其Spring工厂的底层实现原理就是如图所示,第一步通过ClassPathXmlApplicationContext工厂类读取配置文件applicationContext.xml中bean标签的相关信息,例如这里的id值=account class值=这些,然后spring框架通过反射创建对象,反射创建对象的底层也是调用对象自己的构造方法,这两句代码等效于new对象.
问题:未来开发过程中,是不是所有的对象都交给Spring工厂来创建?
答:理论上是的,但是有特例,实体对象(entity),因为实体对象需要调用数据库的,所以实体对象一般都是交于持久层框架(如:MyBatis等)进行创建的。实体包括数据库中数据,但是spring不知道数据库的
这里的配置文件是怎么理解的呢,这就要说到注入
在这里插入图片描述

6.注入

以前我们是怎么给对象的成员变量赋值的呢?
是不是用的set方法,但是这个方法存在耦合,比如说这里,我给person对象用set方法给name属性赋值test,但是当名字改变的时候,需要改变代码,存在耦合
所以就有了注入,注入的概念就是通过读取配置文件,为所创建的对象成员变量赋值,注入有两种方式,set注入和构造注入,我们这里只讲用得多的set注入,它分为两步,首先类成员变量提供set, get方法,然后编写spring配置文件,在bean标签加入property标签, property标签里面是怎么写的呢,我们看下一个例子
在这里插入图片描述
创建的类有两个成员变量,分别提供set ,get方法,这个配置文件里的bean标签等效于new操作,property标签配置对象属性,标签的name属性配置成对象的成员变量名字,value标签里写所要赋的值,这个property的意思是给对象的成员变量name赋值为suns,这个property的意思是给对象的成员变量password赋值为123456在这里插入图片描述
成员变量可能不是integer或string ,还有可能是set,list 或者自己定义的类型、 不同的数据类型,需要嵌套不同的标签,
对象的类型分为JDK内置类型和用户自定义类型, JDK内置类型有分为8种基本类型(int,char,Boolean,byte,long ,float,double,short)和String,数组,set集合,list集合,Map集合,properties集合
在这里插入图片描述
String+8种基本类型直接在bean标签中写值,
数组value标签需要外面加个list标签,
set集合,外面是set标签,核心是set标签,里面的标签根据set存的数据所决定,不一定是value,因为set可以存任意数据,如果是8种基本类型set标签里面放value标签,如果又是set集合,则可以嵌套set标签,
同样,list集合的核心是list标签,
Map集合里面的键值对是Map.entry类型的,所以Map标签里面嵌套entry标签,一个键值对对应一个entry标签, entry标签里面又嵌套一个key标签和value标签, key中的标签根据数据类型,第二个value标签也是
Properties集合外面是标签,里面嵌套prop标签,属性key,因为上面提过properties集合的值只能是string类型所以省略value标签
还有些复杂的JDK类型比如Date类型,需要定义定义自定义类型转换器进行处理。比较复杂,这里就不说了

在这里插入图片描述
用户自定义类型的开发步骤
第一步提供set,get方法
第二步创建自己定义的类的对象(bean
然后通过引用
这里就是将userService对象的userDao属性赋值为userDao对象
在这里插入图片描述
JDK类型把value标签当作property的value属性,简化后是这样的,要注意value属性只能简化8种基本类型+String的value标签。
Map类型entry标签简化,将key和value标签作为entry标签的属性,这里要注意只有单个键值对才能简化,set、list都不能简化。
用户自定义类型,将ref标签当作property的ref属性,简化后是这样的
在这里插入图片描述

7. IOC

接下来我们要讲spring两大核心中的一个,IOC,中文意思是反转控制
控制的含义是成员变量的赋值的控制权
反转控制的意思就是将对象成员变量赋值的控制权由代码反转发到spring配置文件和spring工厂中
这样做的好处是解耦合
底层实现是工厂模式
看这里的图,这里的userServiceImpl类的成员变量userDao是new出来的,直接在代码中完成对成员变量的赋值,对成员变量赋值的控制权是代码,这样是存在耦合的,下面这个代码,用配置文件给成员变量赋值,将将对象成员变量赋值的控制权由代码反转到spring配置文件和spring工厂中
在这里插入图片描述

8.DI

上面我们学了注入,注入的概念是通过Spring的工厂及配置文件,为对象(bean、组件)的成员变量赋值。
那么依赖注入的意思是当一个类需要另一个类时,就意味着依赖,一旦出现依赖,就可以把另一个类作为本类的成员变量,最终通过Spring配置文件进行注入(赋值)。
这样做的好处就是解耦合
比如这个例子,userService要调用userdao的接口,所以可以说userService需要userdao类,需要就是依赖,就可以把另一个类作为本类的成员变量,最终通过Spring配置文件进行注入

在这里插入图片描述

9.代理模式

讲完IOC我们要开始讲spring的另一个核心AOP,在学AOP之前,我们需要讲一些基础知识,首先是代理模式,
为什么需要代理模式设计呢
首先有个问题JavaEE层次中哪层最重要, Service 最重要
那么Service 层中包含了哪些代码?
Service层 = 核心功能(几十上百行代码) +额外功能(附加功能)
核心功能:业务运算、DAO调用(满足用户需求)
额外功能:不属于业务、可有可无、代码量很小(如事务、日志(记录谁+时间+什么事+结果、性能、…)
额外功能书写在Service层中好不好?
Service 层的调用者(Controller)的角度:需要在Service层书写额外功能(事务,保证业务完整性) 软件设计者:Service层不需要额外功能(不好维护,解耦合) 存在矛盾
在这里插入图片描述现实中的问题和解决办法,租房场景,房东想要出租房屋,首先需要贴广告,带租客看房,最后和房客签合同和收钱,这里的广告和看房就是额外功能,房东不想的而且做可以交给其他人的,签合同和收钱是房东必须参与是核心功能,这里房东类比软件设计者不想做额外功功能,房客类比调用者需要额外功能,所以引入一个代理类,里面有额外功能和调用原始类的核心功能
在这里插入图片描述

10.Spring的动态代理

Spring使用的就是动态代理,开发步骤第一步,首先创建原始对象(指的是 业务类(核心功能—→ 业务运算 Dao调用),
这里创建了userservice类,定义了两个方法,注册和登录,然后通过配置文件创建对象
在这里插入图片描述
第二步编写额外功能, Spring提供了MethodBeforeAdvice接口,我们需要把额外功能书写在此接口的实现类的before方法中,这个实现类的before方法会在原始方法执行前先执行。这个before方法的作用:书写运行在原始方法之前的额外功能
参数: Method:额外功能所增加给的那个原始方法(如:login方法、register方法) Object[]:额外功能所增加给的那个原始方法的参数(如login方法的String name, String password) Object:额外功能所增加给的那个原始对象(如UserServiceImpl)
在这里插入图片描述
第三步定义切入点,切入点的意思就是额外功能加入的位置,定义切入点的目的是想要由程序员根据自己的需要,决定额外功能加入给哪个原始方法。这里是简单的测试:所有方法都作为切入点,都加入额外功能。在配置文件中最外面是aop:config标签, 然后配置切入点pointcut,id可任意起,expression是切入点表达式,这里代表所有的方法-execution()是 切入点函数,这个* *(…): 切入点表达式
这个星是返回值,这个星是包.类.方法,比如说这个a是包名,userserviceimpl是类名,*是所有的方法,这个表达式的意思就是a包下UserServiceImpl类中的所有方法都加入额外功能
在这里插入图片描述
第四步是组装二三步,把额外功能和切入点进行整合, advice-ref:额外功能,pointcut-ref:切入点
第五步是获得Spring工厂创建的动态代理对象,并进行调用,这里要注意的是Spring工厂通过原始对象的id值获得的就是代理对象,生成的对象用原始类的接口类型进行接收
这就是spring的两大核心AOP和IOC,了解他们,我们才能体会到spring对于我们项目开发的益处
在这里插入图片描述

二、SpringMVC

1.Spring MVC简介

SpringMVC是基于Spring延伸而来的一个MVC框架,主要解决MVC开发过程中控制器(Controller)的问题
它使用了MVC架构模式的思想。
• M 代表 模型(Model)
模型代表一个存取数据的对象
• V 代表 视图(View)
视图代表模型包含的数据的可视化
• C 代表 控制器(controller)
控制器作用于模型和视图上。它控制数据流向模型对象,并在数据变化时更新视图。它使视图与模型分离开。
刚开始没有controller层,view层直接和model层交互,会出现的弊端: JSP 和 Java Bean 之间严重耦合,Java 代码和 HTML 代码也耦合在了一起 要求开发者不仅要掌握 Java ,还要有高超的前端水平 前端和后端相互依赖,前端需要等待后端完成,后端也依赖前端完成,才能进行有效的测试 代码难以复用
传统的model层被拆分为了业务层(Service)和数据访问层(DAO,Data Access Object)。 在 Service 下可以通过 Spring 的声明式事务操作数据访问层,而在业务层上还允许我们访问 NoSQL ,这样就能够满足异军突起的 NoSQL 的使用了,它可以大大提高互联网系统的性能。
Controller的核心作用:负责service层的调用,接受用户请求,控制程序的运行流程

在这里插入图片描述

2.控制器的作用

没用springmvc时,用的servlet,他的核心功能
1.接受客户端请求参数
2.调用业务对象
3.跳转处理(流程控制)
当要使用Servlet完成的复杂的功能时,需要编写多个Servlet类,并且在web.xml进行注册,这对于完成复杂的Web应用,代码编写会变得很复杂,开发成本也会很高。所以Spring提供了强大的Web开发框架Spring MVC。
在这里插入图片描述
这里是一个用注解写的controller层的代码
使用@Controller 标记一个类是Controller
@Autowired直接放置在成员变量之上,Spring通过反射直接对成员变量进行注入(赋值),也不需要写set方法
使用@RequestMapping定义URL,请求和Controller 方法之间的映射, (项目绑定的路径作为根路径加上这个/signin就可以访问到这个signin方法)
利用@RequestParam 从HttpServletRequest 中绑定了参数userName 到控制器方法参数userName ,绑定了参数password 到控制器方法参数password
这里if语句也是跳转处理
接受客户端请求参数
调用业务对象
跳转处理(流程控制)
在这里插入图片描述

3.与Spring整合核心思路

第一步创建工厂,因为是web项目把之前我们使用的工厂类替换为WebXmlApplicationContext。然后要保证工厂唯一并同时能被共,因为IOC工厂为重量级资源,需要保证一个程序中只有工厂,所以我们需要保证工厂唯一同时能被共用。怎么能被共用呢,我们需要把工厂存储在ServletContext(web应用中唯一的,共享)作用域中。spring的底层实现ServletContext.setAttribute(“xxx”, ctx);Web的作用域有三种,request用户发送一个请求,开始,服务器返回响应,请求结束,生命周期结束。session:用户打开浏览器访问,创建session(开始),session超时或关闭浏览器时,该对象生命周期结束。application:web应用加载的时候创建。Web应用被移除或服务器关闭,对象销毁。怎么保证项目中只有一个工厂,在ServletContext对象创建的同时去创建IOC工厂即可。
利用ServletContextListener监听ServletContext对象的创建,ServletContextListener会在ServletContext对象创建后被调用,把IOC工厂创建的代码写到这个监听器中,实现ServletContext创建后再创建IOC工厂;而由于ServletContext对象唯一,只创建一次,所以这个监听器也就执行一次,从而保证IOC工厂的创建并且唯一。
总结一下就是在serletContext Listener中创建工厂,把工厂存在servletContext中
Spring封装了一个ContextLoaderListener类,帮我们实现了上面创建和保存IOC工厂的代码,我们只需调用即可。(这个类实现了ServletContextListener接口)
在这里插入图片描述
ContextLoaderListener的使用方式:
在web.xml中进行配置
这个监听器会帮我们创建IOC工厂,但是在Spring中,配置文件的位置和名字是任意的,所以我们还需要指定配置文件所在的位置
这里指定配置文件的位置
这是整合的核心思路,具体代码体现之后的实例再讲
在这里插入图片描述

三、Mybatis

1.Mybatis由来

在我们传统的 JDBC 中,我们除了需要自己提供 SQL 外,还必须操作 Connection、Statment、ResultSet,不仅如此,为了访问不同的表,不同字段的数据,我们需要些很多雷同模板化的代码,繁琐又枯燥。代码繁琐、冗余业务代码和数据库的操作混在一起开发效率低,就像右边的这个jdbc代码很长很繁琐
而我们在使用了 MyBatis 之后,只需要提供 SQL 语句就好了,其余的诸如:建立连接、操作 Statment、ResultSet,处理 JDBC 相关异常等等都可以交给 MyBatis 去处理,我们的关注点于是可以就此集中在 SQL 语句上,减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement ; 不用编写关闭资源代码,关注在增删改查这些操作层面上。直接使用 java 对象,表示结果数据。让开发者专注 SQL 的处理。 其他分心的工作由 MyBatis 代劳.
并且 MyBatis 支持使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
在这里插入图片描述

2.开发步骤

Mybatis的开发步骤有七步,第一步创建实体类,属性要和数据库的字段匹配,第二步在mapper配置文件中设置User实体类的别名,因为类的全路径类名很长,而且如果类名改变的话,每个类出现的地方都要改,所以设置别名是很重要的,第三步创建数据表,第四步创建userDao接口,第五步实现usermapper配置文件,这里的namespace是userdao接口的全路径命名,insert标签是插入操作的配置,id配置的是userdao接口方法名, parameterType是参数类型,标签里面是sql语句,第六步在spring配置文件中注册Mapper文件在这里插入图片描述
第七步MyBatisAPI调用(测试)首先读取主配置文件,获取sqlsession工厂对象,然后获取sqsession对象,获取sqlsession对象,获取userdao对象,创建用户,然后调用save方法,最后提交事物,
Spring与MyBatis整合思路主要是对前面四句代码进行封装,首先前两句的目的是创建sqlsessionfactory的,封装后两行基于sqlsessionfactory
创建sqlsession进而创建dao的实现类,首先看一下spring怎么封装前两行代码
在这里插入图片描述

3.与Spring整合思路分析

Spring开发了一个类sqlsessionfactorybean,他的作用就是用于封装sessionFactory创建的代码,在配置文件中进行配置,注意class要写全路径类名,还有这里的mybatis-config.xml是mybatis配置文件,在这个文件里面我们可以看到进行了数据源,别名,mapper文件的注册的配置,我们整合spring后用sqlsessionfactorybean创建sessionFactory,那么怎么得到mybaris配置文件的信息呢,我们需要mybaris配置文件的信息,需要就等同于依赖,依赖就可以注入,就是在配置文件中对成员变量进行赋值,这个datasource就是mybatis-config.xml里的datasource内容,typealiasespakeage就是mybatis配置文件中的typeAliases,mapperLocations是mybatis配置文件中mapper文件注册在这里插入图片描述
Spring开发了MapperScannerConfigure类封装后两句编码,sqlsessionFactoryBeanName指定工厂对象,value的值就是我们上面的ssfb,basePackage指定DAO接口所在的包,包里有很多dao接口比如userdao,productdao等等,spring会自动分辨生成相应的dao的实现类,用MapperScannerConfigure最终就可以创建dao对象,但是怎么获取spring创建的dao对象,之前是用工厂对象的getBean方法通过dao对象的id获取,这里要注意MapperScannerConfigure所创建的dao对象,他的id是原名称首字母小写.在这里插入图片描述

4.整合后编码

整合后的编码步骤就从7步变为4步,省略了第2,6,7步在这里插入图片描述
只需要创建spring工厂,然后获取对象,然后再调用他的save方法即可,且不用编写事务关闭语句,大大简化了开发在这里插入图片描述

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值