1.Struts1的工作原理

wKioL1Q1Il_xfiqqAACDfbf97rE479.jpg

.web应用程序启动就会加载ActionServlet,ActionServlet从配置文件struts-config.xml中读取配置信息,并把它们存放到各种配置对象中。用户发起请求后,按如下步骤执行:

1)用户的请求以HTTP方式传输到服务器上,接受请求的是ActionServlet.

2ActionServlet接收到请求后,会查找Struts-config.xml文件来确定服务器上是否有用户请求的操作,此处用户请求操作应为登陆操作。如果没有,则返回一个用户请求无效的出错信息。

3)当ActionServlet请求找到用户请求的Action后,首先将用户输入的表单参数打包成一个ActionFrom对象。接着ActionServlet再根据struts-config.xml中的配置信息决定是否要执行ActionFrom对象中的Validate方法。若Validate方法执行有错,则返回。否则,继续下一步。

4)系统生成一个用户所请求的Action的实例对象,将ActionFrom对象传递给它,运行其Execute()方法

5execute()执行结束前会生成以和ActionForward类型的对象并将之返回给ActionServlet,该对象的作用是告诉ActionFroward就代表跳转到一个登陆成功的页面。ActionServlet将对之进行分析,其实就相当于接收到一个新的请求,重复(2~5)的过程,直到将某个界面返会给用户为止!

2.Struts2的工作原理

wKiom1Q1IirBAaqyAAF353-1pm8057.jpg


Struts2执行流程

        1、客户端向Servlet容器(如Tomcat)提交一个请求

        2、请求经过一系列过滤器(如ActionContextCleanUp过滤器等)

        3、核心控制器被调用,询问ActionMapper来决定请求是否需要调用某个Action

        4、如果ActionMapper决定需要调用某个Action,核心控制器把控制权委派给ActionProxy (备注:JSP请求无需调用Action

        5ActionProxy通过ConfigurationManager询问框架的配置文件(struts.xml),找到需调用的Action

        6ActionProxy创建一个ActionInvocation的实例

        7ActionInvocation负责调用Action,在此之前会依次调用所有配置的拦截器

        8Action执行完毕,ActionInvocation负责根据结果码字符串在struts.xml的配置中找到对应的返回结果

        9、拦截器被再次执行

        10、过滤器被再次执行

 

3.Struts1与Struts2的区别

特性

Struts1.x

Struts2

Action

Struts1.x要求Action类要扩展自一个抽象基类。Struts1.x的一个共有的问题是面向抽象类编程而不是面向接口编程。

Struts2的Action类实现了一个Action接口。Struts2也提供ActionSupport基类来实现一般使用的接口。当然,Action接口不是必须的。任何使用execute方法的POJO可以被当作Struts 2的Action对象来使用。

线程模型

Struts1.x Action类是单例类,因为只有一个实例来控制所有的请求。单例类策略造成了一定的限制,并且给开发带来了额外的烦恼。Action资源必须是线程安全或者同步的。

Struts2 Action对象为每一个请求都实例化对象,所以没有线程安全的问题。(实践中,servlet容器给每一个请求产生许多丟弃的对象,并且不会导致性能和垃圾回收问题)。

Servlet 依赖

Struts1.x的Action类依赖于servlet  API,当Action被调用时,以Request和Response作为参数传给execute方法。

Struts2的Action和容器无关。Servlet上下文被表现为简单的Maps,允许Action被独立的测试。

易测性

测试Struts1.x的主要问题是execute方法暴露了Servlet API使得测试依赖于容器。第三方扩展,如Struts  TestCase,提供一套Struts1的模拟对象(来进行测试)。

Struts2的Action可以通过初始化、设置属性、调用方法来测试。依赖注入的支持也是测试变得更简单。

捕获输入

Struts1.x使用ActionForm对象来捕获输入。象Action一样,所有的ActionForm必须扩展基类。因为其他的JavaBean不能作为ActionForm使用,开发者经常创建多余的类来捕获输入。DynaBeans可以被用来作为替代ActionForm的类来创建。但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。

Struts2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven 特性简化了taglib对POJO输入对象的引用。

表达式语言

Struts1.x整合JSTL,所以它使用JSTL的表达式语言。表达式语言有基本的图形对象移动,但是对集合和索引属性的支持很弱。

Struts2使用JSTL,但是也支持一个更强大和灵活的表达式语言--"Object Graph Notation Language" (OGNL)。

将值绑定到页面

Struts1.x使用标准JSP机制来绑定对象到页面上下文。

Struts2使用“ValueStack”技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。

类型转换

Struts1.x的ActionForm属性经常都是String。Struts 1.x使用Commons-Beanutils来进行类型转换。转换每一个类,而不是为每一个实例配置。

Struts2使用OGNL进行类型转换。提供基本和常用对象的转换器。

验证

Struts1.x支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。

Struts2支持通过validate方法和XWork校验框架来进行校验。

Action执行控制

Struts1.x支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。

Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。

4.Struts2中拦截器的主要作用、工作原理,如何自定义拦截器

1.拦截器的主要作用

早期MVC框架将一些通用操作写死在核心控制器中,致使框架灵活性不足、可扩展性降低;Struts 2将核心功能放到多个拦截器中实现,拦截器可自由选择和组合,增强了灵活性,有利于系统的解耦。为Action提供附加功能时,无需修改Action代码,使用拦截器来提供。Struts 2大多数核心功能是通过拦截器实现的,比如表单组装、表单验证、类型转换、模型驱动、Servlet对象注入、文件上传等,每个拦截器完成某项功能。

2.Struts2中拦截器的工作原理

拦截器与过滤器原理很相似。三阶段执行周期:1、做一些Action执行前的预处理;2、将控制交给后续拦截器或返回结果字符串;3、做一些Action执行后的处理。多个拦截器可以组成拦截器栈一起起作用。从结构上看,拦截器栈相当于多个拦截器的组合;在功能上看,拦截器栈也是拦截器

3.1自定义拦截器的方法

*       实现Interceptor接口

*       void init():初始化拦截器所需资源

*       void destroy():释放在init()中分配的资源

*       String intercept(ActionInvocation ai) throwsException

*       实现拦截器功能

*       利用ActionInvocation参数获取Action状态

*       返回结果码(result)字符串

*       继承AbstractInterceptor

*       提供了init()destroy()方法的空实现,只需要实现intercept方法即可

*       推荐使用

*       继承MethodFilterInterceptor

*       指定拦截的方法:includeMethods

*       指定不拦截的方法:excludeMethods

3.2配置和引用拦截器

 <interceptors>

<!-- 配置拦截器 -->

<interceptor name="time"

    class="com.aptech.struts2.interceptor.FirstInterceptor"/>

<!-- 配置拦截器栈 -->

<interceptor-stack name="myStack">

<interceptor-ref name="time"/>

interceptor-ref name="defaultStack"/>

</interceptor-stack>

</interceptors>

<!-- 配置默认拦截器 -->

<default-interceptor-ref name="myStack"/>

<action name="login"

class="com.aptech.struts2.action.LoginAction">

        <result>/success.jsp</result>

        <result name="error">/error.jsp</result>                       

<!-- Action指定拦截器 -->      

        <interceptor-ref name="myStack"/>  

</action>

5.拦截器和过滤器的异同

1、过滤器是web项目的普遍概念,而拦截器是struts2中的特有概念

2、过滤器可以过滤所有请求,拦截器只拦截action请求

3、自定义过滤器需要实现Filter接口,而自定义拦截器可以实现Interceptor接口

4、在web.xml中配置过滤器,在struts.xml中配置拦截器

5、拦截器可以访问Servlet APIActionContext、值栈,而过滤器只能访问Servlet API

6、使用通配符来定义过滤器的过滤路径,过滤的是地址。通过为Action指定拦截器来调用拦截器,拦截器可以细化到方法层次。

7、在Struts2项目中如果使用过滤器,一般应该将过滤器置于Struts2总控制器之前

8、执行顺序:过滤器---拦截器---Action---拦截器---过滤器(过滤器靠前)

9、拦截器是基于java的反射机制的,而过滤器是基于函数回调(待确认)

6.Hibernate相比JDBC的优势所在

二者的联系:

JDBCjava应用程序连接数据库,进行数据存取的一种机制,是一组用java语言编写的类和接口的API,它和数据库之间由各个厂商提供的数据库驱动进行关联。hibernate是一个开源的轻量级的ORM框架,它在底层对jdbc进行了封装。Hibernate可以用在任何JDBC可以使用的场合

优点:

1hibernate可以让开发人员以面相对象的思想来操作数据库jdbc只能通过SQL语句将元数据传送给数据库,进行数据操作。而hibernate可以在底层对元数据和对象进行转化,使得开发者只用面向对象的方式来存取数据即可。

2使用的语言不同JDBC使用基于关系型数据库的标准SQL语言,Hibernate使用的是HQL语言

3操作的对象不同JDBC通过SQL语句直接传送到数据库中执行,Hibernate操作的是持久化对象,由底层持久化对象的数据更新到数据库中。

4hibernate开发的程序具有更好的移植性。hibernate使用xmlJPA的配置以及数据库方言等等的机制,使得hibernate具有更好的移植性,对于不同的数据库,开发者只需要使用相同的数据操作即可,无需关心数据库之间的差异。而直接使用JDBC就不得不考虑数据库差异的问题。

5使用Hibernate极大的提高了开发者的开发效率。hibernate提供了大量的封装(这也是它最大的缺点),很多数据操作以及关联关系等都被封装的很好,开发者不需写大量的sql语句,这就极大的提高了开发者的开发效率。

6Hibernate缓存机制对提升性能大有裨益hibernate提供了缓存机制(session缓存,二级缓存,查询缓存),对于那些改动不大且经常使用的数据,可以将它们放到缓存中,不必在每次使用时都去查询数据库,缓存机制对提升性能大有裨益。

缺点:

1、从理论上来说,ORM永远也不可能比JDBC好,就像任何高级语言的运行性能永远也不会好过汇编语言一个道理。但从这个角度讲,精心编写的JDBC无论如何都是最快的。

2hibernate更消耗内存。因为它每次的数据库操作都要做数据和对象的转换/封装,查询出一条数据就要创建一个或多个对象,这样也太消耗内存了。

3、对hibernate而言,它对JDBC封装过于厉害,所以就失去了对SQL的控制(当然hibernate也可以使用nativesql既使用createSQLQuery等方法来调用与数据库相关的sql,但这样一来也就影响了hibernate的可移植性),使得hibernate的在很多地方不够灵活,难于优化,尤其对于一些复杂的关联查询时,hibernate提供的功能远不及直接使用JDBC方便性能更高。

7.Hibenate的基本原理(ORM)

wKioL1Q1ImPzgJ-WAAEucGLRr1g312.jpg

Hibenate的核心是ORM映射。hibernate通过对jdbc进行封装,对 java类和关系数据库进行mapping,实现了对关系数据库的面向对象方式的操作,改变了传统的jdbc + sql操作数据的方式,从而使开发人员可以花更多精力进行对象方面的开发。

8.cascade和inverse的区别

inversecascade两者之间没有任何关系。但是它们又都能影响对象关联关系的维护,所以将这两个属性的作用区分开也不是很容易的。

inversecascade的区别主要表现在以下几个方面:

  作用的范围不同

inverse是设置在集合元素中的,而对于<many-to-one><one-to-one>则无此属性。而cascade则对于所有涉及到关联的元素都是有效的,其中包括了集合元素以及<many-to-one><one-to-one>

  执行的策略不同

inverse会首先判断集合的变化情况,然后针对变化执行相应的处理。而cascade则是直接对集合的每个元素执行相应的处理。

  执行的时机不同

inverse是在执行SQL语句之前判断是否要执行该SQL语句,而cascade则是在主控方发生操作时用来判断是否进行级联操作。

  执行的目标不同

inverse对于<one-to-many><many-to-many>处理不尽相同。对于<one-to-many>inverse所处理的是对被关联表(的外键)进行修改操作。对于<many-to-many>inverse所处理则是中间关联表(增减记录)。而cascade则不会区分这两种关系的差别,所做的操作都是针对被关联表的。

9.HQL和SQL的区别

  1. 1. 操作对象不同:HQL操作的类及其属性,SQL操作的是数据库表及其字段

  2. 2. 相比SQL语句,HQL有所简化

  3. 3. HQL结果直接返回List或其他对象,而不是像JDBC中使用SQL返回结果集,还要转化成对象。

  4. 4. 不同数据库的SQL语句会有细微差别,HQL独立于数据库,根据方言设置转换为对应的SQL语句

  5. 10.如何提高Hibernate的性能

  6. 1.       配置数据源

  7. 2.       使用延迟加载

  8. 3.       使用二级缓存、查询缓存

  9. 4.       HQL语句的优化:避免ornotlikehavingdistinct等操作

  10. 5.       映射文件配置参数:fetch-size, fetch, batch-size

  11. 6.       操作方法使用:比如loadgetlistiterate

  12. 11.Hibernate中持久化类的三种状态及其特征

瞬时状态特征:不在Session缓存中,不与任何Session实例相关联;在数据库中没有与之对应数据。

持久化状态特征:在Session缓存中,与Session实例相关联;在数据库中有与之对应的数据。

脱管状态特征:不在Session缓存中,不与任何Session实例相关联;在数据库中有与之对应数据。

Hibernate会检测到处于持久状态的对象的任何改动,在当前操作单元执行完毕时将对象的状态同步到数据库,开发者不需要手动执行update()语句。多次save()是多余的。

wKiom1Q1Ii7yhJbjAADF-oeXRbs337.jpg

12.SpringIoC的原理

wKioL1Q1ImmgFN_GAADyQPP7xr8527.jpg

采用IoC之前,对象的创建以及对象关系的维护都要由程序员通过硬编码的形式来维护。

采用IoC后,对象的创建以及对象关系的维护将由IoC容器来实现,维护的依据是配置文件,程序员直接从容器中取对象就可以了

13.SpringAOP的原理

wKioL1Q1ImuywroDAADTE85u3Ys977.jpg

AOP,面向切面编程,是一种编程方法,它和面向对象编程采用的顺序(纵向)编程形成互补,可以解决一些在OOP中无法或很难解决的问题,例如事务、日志、权限等横切性问题,使得OOP集中精力于业务逻辑编程。

OOP实现横切性关注点导致代码混乱,开发者必须同时考虑业务逻辑、性能、日志、安全等问题。代码分散,横切性代码散布在各个模块中。AOP将这些代码模块化,然后织入到需要的模块中。

过滤器,拦截器都可以理解为一种AOP技术。

14.AOP的基本概念:切面、通知、切入点、连接点、织入

  1. 1.         切面(Aspect):从对象中抽取出来的横切×××模块。类似与OOP中的一个类。由通知和切入点两部分组成。

  2. 2.         通知(Adivice):切面的具体实现,例如具体的日志操作代码,一般是是切面中的某个方法。

  3. 3.         连接点(Joinpoint):目标对象中插入通知的地方。即advice的应用位置。spring中只支持是方法

  4. 4.         切入点(Pointcut):切面的一部分,对应一个表达式,定义了advice应该被插入到什么样的Joinpoint点上,即 advice的应用范围

  5. 5.         目标对象(Target Object):被通知的对象。

  6. 6.         代理(AOP Proxy):由AOP框架创建的目标对象的代理对象。是被插入了adviceTarget Object

  7. 7.         织入(Weaving):将通知与目标对象结合在一起,生成新的对象的过程。新的对象就是AOP Proxy Spring是在运行是完成织入工作的。


QQ截图20181014143201.jpg