Hi!欢迎光临陕西省的权威思科、华为、Oracle、红帽、深信服、微软认证培训中心!

| 029-88235527
您现在所在位置:首页 > 新闻资讯 > 最新资讯 >

Java面试题| 框架篇

发布日期:2020-05-21 17:19:22点击次数:

分享到:
最近小编时常会收到一些用户的后台留言,比如:“面试”、“2020”、“2020 Java”、“面试题”等等,追溯了下源头,原来就是之前发布的《Java面试大全》作祟,在此我也跟大家再说下,需要完整版JAVA面试题大全的,大家可以后台留言以下关键词:“2020版JAVA”、“2020”、“面试题”、“2020 java” (之前关键词过于复杂,发现大家也懒得写,现在特意增设几个)。
     今天这篇也是应用户在后台留言的需求而另外增设的,给大家整理了一些Java面试框架类内容~话不多说,正式开始:
 
1:SSH框架
 
(1)SSH三大框架的概述
 
SSH为 struts+spring+hibernate的一个集成框架,是目前较流行的一种Web应用程序开源框架。
 
集成SSH框架的系统从职责上分为四层:表示层、业务逻辑层、数据持久层和域模块层(实体层),以帮助开发人员在短期内搭建结构清晰、可复用性好、维护方便的Web应用程序。
 
struts标签库:Struts2默认的表达式语言是OGNL(Object-Graph Navigation Language),通过它可以存取对象的任意属性、调用对象的方法、遍历整个对象的结构图、实现字段类型转换等功能。
 
JSP: HTML文件中插入Java程序段和JSP标记。
 
web.xml: Struts2核心过滤器和监听器
 
struts.xml: 管理应用中的Action映射,及Action处理结果和物理资源之间的映射。
 
applicationContext.xml: 整合了struts和Hibernate。
 
.hbm.xml:O/R Mapping(Object Relational Mapping)映射文件,实体和表的映射关系通过XML来描述的文件。在项目启动的时候加载到内存中。
 
PO:Persistent Object,持久化对象
 
整体的调用关系:JSP–Action–Service–DAO–PO–数据库
 
(2)什么是struts2
 
Struts2是一个基于MVC设计模式的Web应用控制层框架,功能就是完成jsp页面和后台java代码的传值和跳转。
 
Struts2的运行原理
 
1:当前台发送一个以规定后缀相同的请求时 如:.action struts核心控制器会对其进行过滤拦截 核心控制器StrutsPrepareAndExecuteFilter
 
2:核心控制器拦截请求后会根据请求的路径找到对应的java代码,通过路径中的类名(!前的部分)匹配struts.xml中action标签中的name属性来找到具体访问的类,!后的部分匹配类中的方法名
 
3:当java类中完成处理逻辑会返回一个字符串,根据字符串匹配struts.xml中result标签的name属性,然后跳转到result标签内容指定的页面。
 
(3)Spring
 
简单来说,spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。
 
◆ 轻量——从大小与开销两方面而言Spring都是轻量的。完整的Spring框架可以在一个大小只有1MB多的JAR文件里发布。并且Spring所需的 处理开销也是微不足道的。此外,Spring是非侵入式的:典型地, Spring应用中的对象不依赖于Spring的特定类。
 
◆ 控制反转——Spring通过一种称作控制反转(IOC)的技术促进了松 耦合。当应用了IOC,一个对象依赖的其它对象会通过被动的方式传递 进来,而不是这个对象自己创建或者查找依赖对象。这也是说spring是非侵入式的,动态注入对象,让一个对象的创建 不用new,可以自动生成,这就是利用JAVA里的反射,反射其实就是 在运行时动态的去创建、调用对象及其方法,spring就是在运行时,跟 xml spring的配置文件来动态的创建对象,和调用对象里面的方法 反射技术的使用使得我们不再像原始的工厂方法模式那样创建对象。反 射可以非常灵活的根据类的名称创建一个对象。所以spring只使用了 Prototype和Singleton这两个基本的模式。
 
◆ 面向切面——Spring提供了面向切面编程的丰富支持,允许通过分离 应用的业务逻辑与系统级服务(例如审计(auditing)和事务 (transaction)管理,主要实现对事务的管理)进行内聚性的开发,其 机理来自于代理模式。应用对象只实现它们应该做的——完成业务逻辑 ——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例 如日志或事务支持。
 
◆ 容器——Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。凡是在spring的配置文件里面配置了,才能被spring管理;并享用spring提供的服务 。
 
◆ 框架——Spring可以将简单的组件配置、组合成为复杂的应用。在Spring中,应用对象被声明式地组合,典型地是在一个XML文件里。Spring也提供了很多基础功能(事务管理、持久化框架集成等等),将应用逻辑的开发留给了你。所有Spring的这些特征使你能够编写更干净、更可管理、并且更易于测试的代码。它们也为Spring中的各种模块提供了基础支持。
 
谈Spring这个问题的时候,首先Spring中最为重要的无非就是IOC和AOP,而对IOC来讲,你讲一下IOC的定义,IOC就是说对象本身的创建不依赖应用本身,而是依赖于外部容器,如果没有IOC那么我们在我们的业务类,要调用DAO的方法,那么不得不做的一个动作就是创建一个DAO的实现类的实例,而创建这个对象本身是跟业务无关的,而这样违反了“高内聚,低耦合”,使类与类的联系非常紧密了。即使你不用new,你使用工厂模式,使用单利模式,也跟上面说的效果是一样的,而Spring本身就是一个大工厂,他帮我们造对象,帮我们管理bean对象,它帮我们注入我们所需的bean对象,这样对于以后的维护来讲,变的更为方便,也把与业务本身无关的东西提取出来了。体现了低耦合。而AOP本身就是一种思想,意为面向切面编程,而Spring对AOP做了部分实现,(举例说明)如果没有AOP,比如我们开发的系统中有发邮件,写日志,可想而知,系统中发邮件,写日志绝对的不是在一个地方用到,那么怎么办,肯定是在业务中写着重复的代码,而且干着与业务无关的事情,也就是说让发邮件,写日志跟业务一起混合在一起,那么这样肯定是不合理的。那么该怎么办,因此Spring提供了AOP,在你想写日志的方法给你切开,加入日志的操作,刚刚说spring是大工厂,那么对于spring的AOP来讲,我更加喜欢把它比喻成化妆师,只有你让spring帮你化妆,就能达到你意想不到的效果,总的来讲spring的AOP技术,他帮我们做很多与业务无关的操作,让业务层次更加清晰。
 
Spring AOP事务的描述:
 
在applicationContent.xml里通过aop:config里面先设定一个表达式,设定对service里那些方法 如:对add* ,delete*,update*等开头的方法进行事务拦截。我们需要配置事务的传播(propagation=“REQUIRED”)特性,通常把增,删,改以外的操作需要配置成只读事务(read-only=“true”).只读事务可以提高性能。之后引入tx:advice,在tx:advice引用 transactionManager(事务管理),在事务管理里再引入sessionFactory,sessionFactory注入 dataSource,最后通过aop:config引入txAdvice。
 
事物的7种传播特性
 
opropagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。
 
opropagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。
 
opropagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。
 
opropagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。
 
opropagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
 
opropagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。
 
opropagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作
 
Spring默认的事物传播行为是propagation_requierd
 
(4)Hibernate
 
1:hibernate 是什么
 
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。Hibernate可以应用在任何使用JDBC的场合
 
是基于JDBC使用面向对象封装而来的 ORM 持久层框架/数据库中间件
 
2:什么是ORM?
 
O :Object : 对象,
 
R :Relation : 关系型数据库;-->oracle , mysql ,
 
M :Mapping : 映射 ;就是一个 xml 的配置文件,
 
通过配置文件将对象和关系型数据库连接起来实现我们通过操作对象的形式来操作数据库。
 
3:hibernate和jdbc的区别
 
1.jdbc和hibernate都是 数据库中间件/持久层框架 用来操作数据库
 
2.hibernate 是基于 jdbc封装而来
 
不同
 
JDBC
 
1.不能跨数据库 不同的数据库使用不同链接驱动jar包
 
2.使用sql 语句操作数据库
 
3.查询时 结果集需要手动遍历封装到java对象
 
4.执行效率高 开发效率低
 
Hibernate
 
1.能夸数据库 通过方言配置可以切换不同的数据库语言
 
2.通过对象操作数据库 或者是HQL语句不管是通过对象还是HQL语句最终都会变成sql语句执行
 
3.查询时hibernate通过配置的关系 直接返回java对象通过反射机制自动封装对象,反射是很耗费资源的
 
4.执行效率低 开发效率高
 
4:Hibernate核心类
 
Configuration 代表hibernate配置信息的类
 
hibernate启动时通过Configuration类读取数据库配置和映射关系
 
configure()方法加载配置文件
 
buildSessionFactory()构建session工厂
 
SessionFactory 会话工厂 可以认为 是jdbc 中的Connection对象openSession()打开一个回话
 
Session会话类
 
操作数据库的
 
save(对象) 新增
 
get(类型,主键) 只返回一条数据 必须根据主键查询
 
load(类型,主键)只返回一条数据 必须根据主键查询
 
delete(对象) 根据对象的id 删除记录
 
update(对象)根据对象的id修改记录
 
saveOrUpdate(对象) 对象id不存在 执行新增 存在执行修改
 
Transaction 事务
 
transaction.commit();提交事务
 
transaction.rollback();回滚事务
 
Query书写 执行 HQL语句
 
获得 query
 
session.cre=ateQuery(“hql 可以有占位符号”);
 
1.替换占位符号
 
query.setParamenter(“下标从零开始,值”);
 
2.查询 List结果集
 
query.list(); 返回多条数据 以List集合的形式
 
3.获得唯一结果集(必须确定结果集唯一才能使用)
 
uniqueResult(); 只返回一个Object对象
 
4.执行修改数据的操作
 
executeUpdate(); 执行删除 新增 修改的 语句
 
5:主键生成策略
 
increment:适用于short,int,long作为主键 ,不是使用的数据库自动增长,是先查询数据库中最大 的id值,然后在最大的基础上加一,然后赋值 。
 
identity :自动递增,只适用于自动递增的数据库。(oracle不能使用)。
 
sequence:序列,只适用于有序列的数据库。(适用与oracle)。
 
uuid:适用于char,varchar类型的主键。
 
native:本地的。使用数据库本身的方式,
 
(比如oracle是使用序列,而mysql则使用递增)。
 
6:Hibernate缓存
 
缓存是介于应用程序和物理数据源之间,其作用是为了降低应用程序对物理数据源访问的频次,从而提高了应用的运行性能。
 
缓存内的数据是对物理数据源中的数据的复制,应用程序在运行时从缓存读写数据,在特定的时刻或事件会同步缓存和物理数据源的数据。
 
一级缓存 自动开启的 是session的缓存 无需配置 自动使用
 
二级缓存 是需要配置 第三方缓存 例如 OScache 是sessionFactory 的缓存
 
三级缓存/查询缓存 无需配置 自动使用
 
7:Hibernate查询的策略
 
是先从缓存查询对象如果缓存中没有对应条件的对象再发送sql语句查询数据库,如果缓存中存在符合条件的对象就是用缓存中的数据,从而降低查询效率。
 
8:get和load的区别
 
1.get 当查询的id 在缓存和数据库中都不存在的话 返回 null
 
2.load 当查询的id 在缓存和数据库中都不存在的话会发生异常 ObjectNotFoundException
 
load 可以执行 懒加载的操作
 
懒加载功能: 当我们查询一个 hibernate对象时只获得对象的id
 
当使用到对象的其他属性时再去数据库查询其他的信息
 
9:Hibernate对象状态
 
Hibernate中对象有三种状态:临时状态(Transient)、持久状态(Persistent)、游离状态(Detached)。
 
临时状态:刚刚使用new语句创建,还没有被持久化,不处于Session的缓存中。处于临时状态的状态的Java对象被称为临时对象。
 
持久化状态:已经被持久化,加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象。
 
游离状态/托管状态:已经被持久化,但不处于session的缓存中。处于游离状态的Java对象被称为游离对象。
 
10:为什么使用hibernate
 
1)、对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码。
 
2)、Hibernate是一个优秀的ORM实现。他很大程度的简化DAO层的编码工作,将软件开发人员从大量相同的数据持久层相关编程工作中解放出来,使开发更对象化了。
 
3)、移植性好,支持各种数据库,如果换个数据库只要在配置文件中变换配置就可以了,不用改变hibernate代码。
 
4)、支持透明持久化,因为hibernate操作的是纯粹的(pojo)java类,没有实现任何接口,没有侵入性。所以说它是一个轻量级框架。
 
11:谈谈你对Hibernate的理解。
 
面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象、建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化。
2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息。从Java程序的运行功能上来讲,保存对象状态的功能相比系统运行的其他功能来说,应该是一个很不起眼的附属功能,java采用jdbc来实现这个功能,这个不起眼的功能却要编写大量的代码,而做的事情仅仅是保存对象和恢复对象,并且那些大量的jdbc代码并没有什么技术含量,基本上是采用一套例行公事的标准代码模板来编写,是一种苦活和重复性的工作。
3.通过数据库保存java程序运行时产生的对象和恢复对象,其实就是实现了java对象与关系数据库记录的映射关系,称为ORM(即Object Relation Mapping),人们可以通过封装JDBC代码来实现了这种功能,封装出来的产品称之为ORM框架,Hibernate就是其中的一种流行ORM框架。使用Hibernate框架,不用写JDBC代码,仅仅是调用一个save方法,就可以将对象保存到关系数据库中,仅仅是调用一个get方法,就可以从数据库中加载出一个对象。
4.使用Hibernate的基本流程是:配置Configuration对象、产生SessionFactory、创建session对象,启动事务,完成CRUD操作,提交事务,关闭session。
5.使用Hibernate时,先要配置hibernate.cfg.xml文件,其中配置数据库连接信息和方言等,还要为每个实体配置相应的hbm.xml文件,hibernate.cfg.xml文件中需要登记每个hbm.xml文件。
6.在应用Hibernate时,重点要了解Session的缓存原理,级联,延迟加载和hql查询。
(5)SSH整合
在项目中首先是通过在web.xml中配置strtus2的前端控制器StrutsPrepareAndExecuteFilter加载struts.xml
配置文件并对指定的后缀名进行拦截,并且通过配置spring的监听器contextLoadListener
加载spring的相关配置文件如
spring-service.xml,spring-dao.xml,spring-common.xml,
之后新建控制层的类继承于BaseAction,而BaseAction继承于ActionSupport,
在BaseAction中封装了常用的方法如getRealPath(),outJson()等,
之后控制层注入service层,service层注入dao,dao层继承于HibernateDaoSupport
并注入spring-common.xml中配置的sessionFactory,sessionFactory注入dataSource连接数据库,
注入hibernate.cfg.xml从而加载hbm.xml文件,
除此之外还通过Spring中的Aop配置了事务并且通过切点表达式对Servcie层代码进行控制。
(6)总结
在SSH中使用Struts作为系统的整体基础架构,负责MVC的分离,在Struts框架的模型部分,控制业务跳转,利用Hibernate框架对持久层提供支持,Spring做支持,支持struts和hibernate。具体做法是:用面向对象的分析方法根据需求提出一些模型,将这些模型实现为基本的Java对象,然后编写基本的DAO(Data Access Objects)接口,并给出Hibernate的DAO实现,采用Hibernate架构实现的DAO类来实现Java类与数据库之间的转换和访问,最后由Spring做支持,支持struts和hibernate。其实ssh框架最主要的本质是:“高内聚、低耦合”。
SSH框架优点:
1.spring管理对象的实例化,把对象的创建和获取放到外部,更加的灵活方便。
2.Hibernate避免了JDBC连接数据库的冗余繁杂。
3.各层分工明细,实现了各层之间的解耦,代码更加灵活。
2:SSM框架
 
(1)SSM框架概述
 
SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层
 
使用spring MVC负责请求的转发和视图管理
 
spring实现业务对象管理,mybatis作为数据对象的持久化引擎
 
(2)SpringMVC
 
1:介绍
 
Spring MVC是基于组件技术的,全部的应用对象,无论是控制器和视图,还是业务对象之类的都是java组件,并且spring mvc 不依赖于Servlet API,可以任意使用任何视图技术,支持各种请求资源的映射策略,并且spring mvc是易于扩展的。
 
2:运行原理
 
Spring mvc的运行原理是从一个HTTP请求开始:Tomcat在启动时加载解析web.xml,找到spring mvc的前端总控制器DispatcherServlet,并且通过DispatcherServlet来加载相关的配置文件信息。DispatcherServlet接收到客户端请求,找到对应HandlerMapping,根据映射规则,找到对应的处理器(Handler)。调用相应处理器中的处理方法,处理该请求后,会返回一个ModelAndView。DispatcherServlet根据得到的ModelAndView中的视图对象,找到一个合适的ViewResolver(视图解析器),根据视图解析器的配置,DispatcherServlet将要显示的数据传给对应的视图,最后显示给用户。
 
3:常用注解
 
我在使用spring mvc的时候用到了很多注解,比如@RequestMapping在类面前定义,将url和类绑定。在方法面前定义 ,则将url和类的方法进行绑定。还有@RequestParam一般用于将指定的请求参数付给方法中的形参。
 
@Responsebody是将对象转换为json格式进行传输。
 
@Autowired和@Resource注解的作用都是为了进行属性注入,@Autowired默认是按照类型进行匹配的是spring提供的注解,@Resource默认是按照名字进行匹配,它是 java提供的注解 ,我一直在项目中使用的是@Autowired注入。
 
4:注意
 
spring和MVC是父子容器关系,spring是父容器,MVC是子容器.子能访问父中的对象,而父却不能访问子容器中的对象.基于这点我们还可以深入一下,不用spring容器,只用mvc容器是可以的,因为它里面可以同时扫描controller层.service层.dao层的注解.而不用mvc容器,只用spring容器是不可以的,下面我们来查看具体原因,翻看源码,从SpringMVC的DispatcherServlet开始往下找,我们发现SpringMVC初始化时,会寻找SpringMVC容器中的所有使用了@Controller注解的Bean,来确定其是否是一个handler。springMVC容器中并没有注册带有@Controller注解的Bean,而是把所有带有@Controller注解的Bean都注册在Spring这个父容器中了,所以springMVC找不到处理器,不能进行跳转。springmvc中处理器映射器的底层原理,是一个map(“url路径”,controller的方法)。通过拦截请求得到相应的url路径,然后从map中找对象的controller方法。
 
5:在springmvc 和 spring 都有注解扫描的前提下,不能将事务配置在Controller层?
 
因为事务管理器是配置在spring容器中的,如果将事务配置在Controller层的话,spring容器就访问不了springmvc子容器,进而无法访问到事务对象。进而导致事务失效.
 
(3)Mybatis
 
1:介绍
 
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
 
2:Mybatis的缓存分为一级缓存和二级缓存。
 
一级缓存是sqlSession级别的缓存,是基于HashMap的本地缓存,不同的sqlsession之间的缓存数据区域互不影响,一级缓存的作用于是sqlsession范围,当同一个sqlsession执行两次相同的SQL语句时,第一次执行完后会将数据库中插叙到的数据写到缓存,第二次查询从缓存中获取,不用去查询数据库。当sqlsession执行insert,update,delete操作并提交到数据库时,会先清空缓存,保证缓存中的数据是最新数据。mybatis默认开启的是一级缓存。
 
二级缓存是mapper级别的缓存,同样是基于HashMap进行存储,多个sqlsession可以共用二级缓存,其作用域是mapper的同一个namespace。不同色sqlsession两次执行相同的namespace下的相同的SQL语句时,会执行相同的SQL,第二次查询只会查询第一次查询时读取数据库后写到缓存的数据,不会再去数据库查询。
 
3:jdbc,mybatis,hibernate的区别
 
Hibernate属于全自动, mybatis属于半自动,Jdbc属于手动,从开发效率上讲hibernate较高, mybatis居中,jdbc较低,从执行效率上讲hibernate较低,mybatis居中,jdbc较高,因为jdbc是手工写sql语句,程序员对sql的控制能力更大,可以根据业务需要进行优化,而mybatis虽然也可以对sql进行优化,但是他里面将resultset封装为实体的过程中采用了反射机制所以一定程度上影响了性能,但是Mybatis可以支持mapping映射,直接写一个mapper接口,交给spring来管理,只要接口的方法名和sql的id保持一致,就可以轻松的调用方法。而hibernate因为高度封装所以开发效率相对较高,但正因为这个原因,所以程序员在对sql语句的控制和优化方面相对比较弱,而且在将resultset封装成实体的过程中也采用了反射机制,所以在性能方面比起MyBatis较低。
 
3:JDBC
 
JDBC:是java data base connectivity缩写。用java连接数据库
 
Jdbc作用:
 
(1)建立与数据库的连接
 
(2)发送sql语句到数据库
 
(3)处理返回的结果集
 
如何使用JDBC?
 
(1)准备ojdbc版本号.jar(比如ojdbc14.jar)
 
(2)jar包是什么?jar包就是封装好相应功能代码的类,通过jar包的导入,可以让程序直接
 
(3)使用jar包中的方法、属性等
 
使用jdbc操作数据库:
 
(1)导jar包
 
(2)加载驱动,为数据库连接做准备Class.forName(“oracle.jdbc.driver.OracleDriver”)
 
(3)准备用户名,口令,等连接数据库
 
DriverManager.getConnection(“jdbc:oracle:thin:@localhost:1521:xe”, “xxx”, “xxx”)
 
(4)写sql语句
 
(5)创建数据库操作对象
 
(6)执行sql语句
 
(7)关闭连接,释放资源
 
Class.forName的作用?为什么要用?
 
按参数中指定的字符串形式的类名去搜索并加载相应的类,如果该类字节码已经被加载过,则返回代表该字节码的Class实例对象,否则,按类加载器的委托机制去搜索和加载该类,如果所有的类加载器都无法加载到该类,则抛出ClassNotFoundException。加载完这个Class字节码后,接着就可以使用Class字节码的newInstance方法去创建该类的实例对象了。
 
有时候,我们程序中所有使用的具体类名在设计时(即开发时)无法确定,只有程序运行时才能确定,这时候就需要使用Class.forName去动态加载该类,这个类名通常是在配置文件中配置的,例如,spring的ioc中每次依赖注入的具体类就是这样配置的,jdbc的驱动类名通常也是通过配置文件来配置的,以便在产品交付使用后不用修改源程序就可以更换驱动类名。
 
4:微服务框架
 
4.1:什么是微服务?
 
简而言之,微服务架构风格这种开发方法,是以开发一组小型服务的方式来开发一个独立的应用系统的。其中每个小型服务都运行在自己的进程中,并经常采用HTTP资源API这样轻量的机制来相互通信。这些服务围绕业务功能进行构建,并能通过全自动的部署机制来进行独立部署。这些微服务可以使用不同的语言来编写,并且可以使用不同的数据存储技术。对这些微服务我们仅做最低限度的集中管理。
 
4.2:微服务具备的特性?
 
每个微服务可独立运行在自己的进程里;
一系列独立运行的微服务共同构建起了整个系统;
每个服务为独立的业务开发,一个微服务一般完成某个特定的功能,比如:订单管理、用户管理等;
微服务之间通过一些轻量的通信机制进行通信,例如通过REST API或者RPC的方式进行调用。
4.3:微服务优点
易于开发和维护,启动较快,局部修改容易部署,技术栈不受限,按需伸缩,DevOps
4.4:微服务带来的挑战
运维要求较高,分布式的复杂性,接口调整成本高,重复劳动
4.5:微服务设计原则
单一职责原则,服务自治原则,轻量级通信原则,接口明确原则
1:SpringBoot
 
Springboot框架在使用过程中也是比较简单的,我们当时整合mybatis后,直接启动就可以使用了。整合mybatis也是比较简单的,首先在pom.xml中,配置加载spring-boot-starter-parent父类jar包,再引入spring-boot-starter配置。如果是搭建了web项目的话,还需要引入spring-boot-data-web jar包,当时我们是整合mybatis持久层框架,所以需要导入mybatis-spring-boot-starter和mysql-connecter-java整合包,这样就配置完成了。
 
另外项目中链接数据源有两种方式,通过application.properties文件,或者application.yml文件,配置文件中必须安装数据库链接设置。因为springboot没有配置文件,所有的加载都是通过注解来生效的,使用的注解也比较多。
 
项目启动的时候,使用@SpringbootApplication放到启动类上,直接执行main方法就可以了,需要注意的是启动类必须放到根包下,这样才能扫描到所有的类。我们还需要在控制层类上加上@RestController注解(他相当于是spring-mvc中的@ResponseBody和@Controller的结合),其他的注解和spring,spring-mvc的注解差不多了,比如@Controller,@RequestMapping,@Service,@PathVilable,@Value等。用generator生成基本的增删改查,复杂业务逻辑写sql语句。
 
除了使用mybatis外,当时我们还查到了springboot和jpa的整合,因为jpa是不写入sql的所以当时就没有使用,其实jpa使用起来挺简单的,它是通过方法名来进行对数据库的操作,方法名的命名也是要有一定的规则的,dao层的接口需要继承JpaRepositort<>。
 
在我们的项目中,考虑到相应的节假日,网站活动的调整和页面的渲染,所以采用了页面静态化的处理,我们用的是thymeleaf,其实也可以用freemarker,但是当时我上网查了一下发现springboot整合thymeleaf比较好一些,所以就是用了thymeleaf。
 
Thymeleaf也是一款用于渲染xml、xhtml、html5内容的模板引擎,其实跟valocity和freem
 
arker差不多,我在网上看了一下,thymeleaf和springboot整合还是很好用的,结构很明显,只是在对应的标签中加上对应的属性就行了。如th:text设置文本内容,th:href设置路径,th:each循环数据等。
 
另外springboot还可以整合前段框架,有一个webjars官网可以直接找到前段配置的jar包,直接引入到pom.xml中,让前段框架也交给maven处理。
 
考虑到项目中要使用redis缓存服务器,我们当时就整合了redis的主从配置5台redis缓存服务器,还有哨兵机制。整合redis也比较简单,也是在pom.xml中配置引入spring-boot-starter-data-redis,当时我上网查了一下发现,redis的1.4.7版本以上的需要引入spring-boot-starter-data-redis,而1.4.7版本以下的需要引入spring-boot-starter-redis。在application.properties文件中引入redis的相关配置,有端口号,ip地址,链接的数据库等,直接配置就可以,只要redis服务器启动,项目就可以使用了。当时配置的时候,在启动类上加 @EnableCaching注解,开启缓存,这样就可以在业务层实现类的方法上面加上@Cacheable注解就可以使用了,这时候加载到方法后,首先去redis当中取对应数据,如果有数据,从缓存当中获取,如果没有对应数据,再从数据库中获取数据。
 
当时项目中也涉及到了多数据源的动态切换,在以前的项目中我们是使用spring的aop前置通知类实现数据源的动态切换,使用aop前置通知判断到底是什么操作,如果是增删改的操作,切换到主数据库,如果是查询操作,切换到从数据库。现在使用springboot,实现动态切换数据源就比较简单了。首先在application.properties文件中,配置多个数据源链接信息,使用的时候持久层接口通过包结构来区分到底走哪一个数据库。写一个配置类,在类上面加上,@Configuration、@MapperScan(basePackages=“”,sqlSessionTemplateRef=)
 
来设置配置,有几个数据源,配置几个配置类,然后在项目中通过业务逻辑类判断到底走哪一个数据源。
 
另外,在项目中还配置了RabbitMQ消息队列服务器,rabbitMQ是一个异步通信,与activeMQ相比,只是多了一个交换机的概念,它主要包括,生产者、交换机、队列、消费者。它的配置也比较简单,在pom.xml文件中加载对应的jar包spring-boot-starter-amqp,amqp是高级消息队列协议,消息生产者调用AmqpTemplate rabbitTemplate,直接使用rabbitTempla.convertAndSend(message),发送到rabbitMQ中,通过交换机放到指定的队列当中,消费者通过@RabbitListener(queues=””)来监听对应的队列获得信息,通过@RabbitHandler注解来处理监听到的信息。
 
消息队列,容易丢失队列数据如何处理?:
 
解决方案:1.使用mongodb进行数据的备份,电商业务下订单时, 会将所有的订单先发送到消息队列中,供后续监听获得数据操作,为了防止订单数据丢失问题,使用mongodb数据库下订单时,发送到rabbitmq的同时,会将订单信息存入mongodb中备份,同时添加一个标识字段0:未对账,1:已对账。
 
2.另外设置一个springboot定时器,每月月底定时查阅mongodb数据库中一个月以前的数据信息,如果发现mongodb数据信息中有标识还为0:未对账的信息,会将该条信息重新加入到消息队列中进行处理)。刚才说道定时器了,我们也没有使用Quartz定时器,我们使用的是springboot整合的定时器,直接在springboot启动类上添加@EnableScheduling就可以,然后再具体执行的类上加上@Scheduled(cron="*/6 * * * * ?"), 通过表达式来定义。另外还有发邮件功能,pom.xml配置文件中添加spring-boot-starter-mail.
 
Springboot整合mongodb也比较简单,在pom.xml中加载配置spring-boot-starter-data-mongodb,然后在application.properties文件中配置mongodb数据库链接信息,spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test,如果有多个IP集群:spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database创建实体dao,在持久层注入MongoTemplate模板,使用模板来实现对数据库的ICUD操作。
 
如果是多个数据源,在pom.xml文件中加入lombok和spring-boot-autoconfigure包引用。
 
Lombok - 是一个可以通过简单的注解形式来帮助我们简化消除一些必须有但显得很臃肿的Java代码的工具,通过使用对应的注解,可以在编译源码的时候生成对应的方法。加上注解我们就不用手动写 getter\setter、构建方式类似的代码了。
 
spring-boot-autoconfigure - 就是spring boot的自动化配置.
 
在application.properties文件中加入额外的数据源信息.配置不同包路径下使用不同的数据源,通过@Configuration申明配置类@EnableMongoRepositories注解指出包的路径,创建两个库分别对应的对象和Repository借助lombok来构建对象,到此,mongodb多数据源的使用已经完成。
 
2:SpringCloud
 
Spring Cloud是一系列框架的有序集合。它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用Spring Boot的开发风格做到一键启动和部署。Spring并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过Spring Boot风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
 
微服务是可以独立部署、水平扩展、独立访问(或者有独立的数据库)的服务单元,Spring Cloud就是这些微服务的大管家,采用了微服务这种架构之后,项目的数量会非常多,Spring Cloud做为大管家就需要提供各种方案来维护整个生态。
 
Spring Cloud就是一套分布式服务治理的框架,既然它是一套服务治理的框架,那么它本身不会提供具体功能性的操作,更专注于服务之间的通讯、熔断、监控等。