常用框架详解

Hibernate和Mybatis区别

第一方面:开发速度的对比
就开发速度而言,Hibernate的真正掌握要比Mybatis来得难些。Mybatis框架相对简
单很容易上手,但也相对简陋些。个人觉得要用好Mybatis还是首先要先理解好
Hibernate。
比起两者的开发速度,不仅仅要考虑到两者的特性及性能,更要根据项目需求去考虑
究竟哪一个更适合项目开发,比如:一个项目中用到的复杂查询基本没有,就是简单
的增删改查,这样选择hibernate效率就很快了,因为基本的sql语句已经被封装好
了,根本不需要你去写sql语句,这就节省了大量的时间,但是对于一个大型项目,复
杂语句较多,这样再去选择hibernate就不是一个太好的选择,选择mybatis就会加快
许多,而且语句的管理也比较方便。
第二方面:开发工作量的对比
Hibernate和MyBatis都有相应的代码生成工具。可以生成简单基本的DAO层方法。针
对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好
的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。
第三方面:sql优化方面
Hibernate的查询会将表中的所有字段查询出来,这一点会有性能消耗。Hibernate也
可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。而
Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。
Hibernate HQL语句的调优需要将SQL打印出来,而Hibernate的SQL被很多人嫌弃因
为太丑了。MyBatis的SQL是自己手动写的所以调整方便。但Hibernate具有自己的日
志统计。Mybatis本身不带日志统计,使用Log4j进行日志记录。
第四方面:对象管理的对比
是完整的对象关系映射解决方案它提供对象状态管(
Hibernate 是完整的对象/关系映射解决方案,它提供了对象状态管理(state
management)的功能,使开发者不再需要理会底层数据库系统的细节。也就是说,
相对于常见的 JDBC/SQL 持久层方案中需要管理 SQL 语句,Hibernate采用了更自然
的面向对象的视角来持久化 Java 应用中的数据。
换句话说,使用 Hibernate 的开发者应该总是关注对象的状态(state),不必考虑
SQL 语句的执行。这部分细节已经由 Hibernate 掌管妥当,只有开发者在进行系统性
能调优的时候才需要进行了解。而MyBatis在这一块没有文档说明,用户需要对对象
自己进行详细的管理。
5. 第五方面:缓存机制
Hibernate缓存
Hibernate一级缓存是Session缓存,利用好一级缓存就需要对Session的生命周期进
行管理好。建议在一个Action操作中使用一个Session。一级缓存需要对Session进行
严格管理。
Hibernate二级缓存是SessionFactory级的缓存。 SessionFactory的缓存分为内置缓
存和外置缓存。内置缓存中存放的是SessionFactory对象的一些集合属性包含的数据
(映射元素据及预定SQL语句等),对于应用程序来说,它是只读的。外置缓存中存放的是
数据库数据的副本,其作用和一级缓存类似.二级缓存除了以内存作为存储介质外,还可
以选用硬盘等外部存储设备。二级缓存称为进程级缓存或SessionFactory级缓存,它
可以被所有session共享,它的生命周期伴随着SessionFactory的生命周期存在和消
亡。
MyBatis缓存
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。MyBatis
3 中的缓存实现的很多改进都已经实现了,使得它更加强大而且易于配置。
默认情况下是没有开启缓存的,除了局部的 session 缓存,可以增强变现而且处理循环
依赖也是必须的。要开启二级缓存,你需要在你的 SQL 映射文件中添加一行:
<cache/>字面上看就是这样。这个简单语句的效果如下:

  • 映射语句文件中的所有 select 语句将会被缓存。
  • 映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
  • 缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。
  • 根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序
    来刷新。
  • 缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
  • 缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而
    且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
    所有的这些属性都可以通过缓存元素的属性来修改。
    所有的这些属性都可以通过缓存元素的属性来修改。
    比如:
    这个更高级的配置创建了一个 FIFO 缓存,并每隔 60 秒刷新,存数结果对象或列表的
    512 个引用,而且返回的对象被认为是只读的,因此在不同线程中的调用者之间修改它们
    会 导致冲突。可用的收回策略有, 默认的是 LRU:
  • LRU – 最近最少使用的:移除最长时间不被使用的对象。
  • FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
  • SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
  • WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
  • flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒 形
    式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
  • size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的 可
    用内存资源数目。默认值是1024。
  • readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓
    存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。可读写
    的缓存 会返回缓存对象的拷贝(通过序列化) 。这会慢一些,但是安全,因此默认是
    false。

相同点:Hibernate和Mybatis的二级缓存除了采用系统默认的缓存机制外,都可以通
过实现你自己的缓存或为其他第三方缓存方案,创建适配器来完全覆盖缓存行为。
不同点:Hibernate的二级缓存配置在SessionFactory生成的配置文件中进行详细配
置,然后再在具体的表-对象映射中配置是那种缓存。
MyBatis的二级缓存配置都是在每个具体的表-对象映射中进行详细配置,这样针对不
同的表可以自定义不同的缓存机制。并且Mybatis可以在命名空间中共享相同的缓存
配置和实例,通过Cache-ref来实现。
两者比较:因为Hibernate对查询对象有着良好的管理机制,用户无需关心SQL。所以
在使用二级缓存时如果出现脏数据,系统会报出错误并提示。
而MyBatis在这一方面,使用二级缓存时需要特别小心。如果不能完全确定数据更新
操作的波及范围,避免Cache的盲目使用。否则,脏数据的出现会给系统的正常运行
带来很大的隐患。
第六方面:总结
相同点:Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生
成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执
行事务和SQL语句。其中SessionFactoryBuider,SessionFactory,Session的生命
周期都是差不多的。
Hibernate和MyBatis都支持JDBC和JTA事务处理。
Mybatis优势
MyBatis可以进行更为细致的SQL优化,可以减少查询字段。
MyBatis容易掌握,而Hibernate门槛较高。
Hibernate优势
Hibernate的DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映
射。
Hibernate对对象的维护和缓存要比MyBatis好,对增删改查的对象的维护要
方便。
Hibernate数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库
需要写不同SQL。
Hibernate有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供
的缓存机制不佳。

Struts2 和SpringMVC 在请求-响应模型的上的区别。

Struts2处理请求是为每个请求都创建一个单独的Action类,Action类当中的Field属性
参数作为输入和输出参数用IOC来依赖注入的方式,是基于类的。多例的
而SpringMVC则采用输入Request和Reponse作为参数,返回ModelAndView的方
式,是单例的模式,且是基于方法的模式。

无论是在web系统的开发中,还是在网络游戏的开发中,都会牵涉到request和
response参数的处理问题,如何将request和reponse参数对应到我们的设计中,采用
什么样的方式,处理情况是各种各种的。

SpringMVC的几大组件:
1)DispatcherServlet 根据请求的不同,将请求分发到不同的Controller处理器
2)Dispatcher 具体处理请求,返回逻辑视图
3)Handler Mapping
3)ModelAndView 返回的逻辑视图,注意,是逻辑视图,并不是真正的视图比如
JSP页面,而是通过通过视图解析器VierResoler解气逻辑视图,返回真正的要发送给
前端的视图
) 视图解析类
4)ViewResolver View 视图解析类

struts2是通过filter实现的请求转发(或者说请求的初步处理)和初始化操作
springmvc是通过servlet实现的请求转发和初始化

Spring

什么是Spring?

Spring是一个开源的Java EE开发框架。Spring框架的核心功能可以应用在任何Java
应用程序中,但对Java EE平台上的Web应用程序有更好的扩展性。Spring框架的目
标是使得Java EE应用程序的开发更加简捷,通过使用POJO为基础的编程模型促进良
好的编程风格。

Spring有哪些优点?

  • 轻量级:Spring在大小和透明性方面绝对属于轻量级的,基础版本的Spring框架大约
    只有2MB。
  • 控制反转(IOC):Spring使用控制反转技术实现了松耦合。依赖被注入到对象,而不是
    创建或寻找依赖对象。
  • 面向切面编程(AOP): Spring支持面向切面编程,同时把应用的业务逻辑与系统的服
    务分离开来。
    容器:Spring包含并管理应用程序对象的配置及生命周期。
  • MVC框架:Spring的web框架是一个设计优良的web MVC框架,很好的取代了一些
    web框架。
  • 事务管理:Spring对下至本地业务上至全局业务(JAT)提供了统一的事务管理接口。
  • 异常处理:Spring提供一个方便的API将特定技术的异常(由JDBC, Hibernate, 或JDO
    抛出)转化为一致的、Unchecked异常。

Spring框架有哪些模块?

Spring框架的基本模块如下所示:

  • Core module
  • Bean module
  • Context module
  • Expression Language module
  • JDBC module
  • ORM module
  • OXM module
  • Java Messaging Service(JMS) module
  • Transaction module
  • Web module
  • Web-Servlet module
  • Web-Struts module
  • Web-Portlet module

Spring IoC容器

Spring IOC负责创建对象、管理对象(通过依赖注入)、整合对象、配置对象以及管理
这些对象的生命周期。
Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。如何理解好Ioc呢?理解好Ioc的关键是要明确“谁控制谁,控制什么,为何是反转(有反转就应该有正转了),哪些方面反转了”,那我们来深入分析一下:

  • 谁控制谁,控制什么:传统Java SE程序设计,我们直接在对象内部通过new进行创建对象,是程序主动去创建依赖对象;而IoC是有专门一个容器来创建这些对象,即由Ioc容器来控制对 象的创建;谁控制谁?当然是IoC 容器控制了对象;控制什么?那就是主要控制了外部资源获取(不只是对象包括比如文件等)。
  • 为何是反转,哪些方面反转了:有反转就有正转,传统应用程序是由我们自己在对象中主动控制去直接获取依赖对象,也就是正转;而反转则是由容器来帮忙创建及注入依赖对象;为何是反转?因为由容器帮我们查找及注入依赖对象,对象只是被动的接受依赖对象,所以是反转;哪些方面反转了?依赖对象的获取被反转了。

IOC优点
IOC或依赖注入减少了应用程序的代码量。它使得应用程序的测试很简单,因为在单
元测试中不再需要单例或JNDI查找机制。简单的实现以及较少的干扰机制使得松耦合
得以实现。IOC容器支持勤性单例及延迟加载服务。
Spring中的依赖注入
依赖注入作为控制反转(IOC)的一个层面,可以有多种解释方式。在这个概念中,你不
用创建对象而只需要描述如何创建它们。你不必通过代码直接的将组件和服务连接在
一起,而是通过配置文件说明哪些组件需要什么服务。之后IOC容器负责衔接。
有哪些不同类型的IOC(依赖注入)?
构造器依赖注入:构造器依赖注入在容器触发构造器的时候完成,该构造器有一系列
的参数,每个参数代表注入的对象。

<bean id="uaccChannelConfigManager" class="com.alitrip.hotel.ebooking.common.UaccChannelConfigManager">
        <constructor-arg index="0" ref="uaccClientProperty"/>
        <constructor-arg index="1" ref="uaccListener"/>
        <constructor-arg index="2" value="${uacc.nodePath}"/>
        <constructor-arg index="3" value="${uacc.configKey}"/>
    </bean>

Setter方法依赖注入:首先容器会触发一个无参构造函数或无参静态工厂方法实例化
对象,之后容器调用bean中的setter方法完成Setter方法依赖注入。

<bean class="com.alibaba.jv.jveye.client.factory.JveyeFactory">
        <property name="appName" value="${jveye.appName}"></property>
        <property name="host" value="${jveye.host}"></property>
        <property name="currentEnv" value="${jveye.env}"></property>
    </bean>

你可以同时使用两种方式的依赖注入,最好的选择是使用构造器参数实现强制依赖注
入,使用setter方法实现可选的依赖关系。

Spring Beans

Spring Beans是构成Spring应用核心的Java对象。这些对象由Spring IOC容器实例
化、组装、管理。这些对象通过容器中配置的元数据创建,例如,使用XML文件中定
义的创建。
Spring中创建的beans默认都是单例的beans。在bean标签中有一个属性
为”singleton”,如果设为true,该bean是单例的,如果设为false,该bean是原型
bean。Singleton属性默认设置为true。因此,spring框架中所有的bean都默认为单
例bean。

定义bean的作用域
在Spring中创建一个bean的时候,我们可以声明它的作用域。只需要在bean定义的
时候通过’scope’属性定义即可。例如,当Spring需要产生每次一个新的bean实例
时,应该声明bean的scope属性为prototype。如果每次你希望Spring返回一个实
例,应该声明bean的scope属性为singleton。

Spring中支持的bean作用域

  • Spring框架支持如下五种不同的作用域:
  • singleton:在Spring IOC容器中仅存在一个Bean实例,Bean以单实例的方式存在。
  • prototype:一个bean可以定义多个实例。
  • request:每次HTTP请求都会创建一个新的Bean。该作用域仅适用于
  • WebApplicationContext环境。
  • session:一个HTTP Session定义一个Bean。该作用域仅适用于
  • WebApplicationContext环境.
  • globalSession:同一个全局HTTP Session定义一个Bean。该作用域同样仅适用于
  • WebApplicationContext环境.
  • bean默认的scope属性是’singleton‘。

Spring框架中的单例beans不是线程安全的。但是,只要是无状态的对象,不管单例多例都是线程安全的
无状态的对象即是自身没有状态的对象,自然也就不会因为多个线程的交替调度而破坏自身状态导致线程安全问题。无状态对象包括我们经常使用的DO、DTO、VO这些只作为数据的实体模型的贫血对象,还有Service、DAO和Controller,这些对象并没有自己的状态,它们只是用来执行某些操作的。
也就说明了类内使用的声明为什么要设置成私有的,这样的话对象的属性就不会被随意篡改,才是无状态对象。

Spring框架中bean的生命周期

  • 实例化bean对象(通过构造方法或者工厂方法)
  • 设置对象属性(setter等)(依赖注入)
  • 如果Bean实现了BeanNameAware接口,工厂调用Bean的setBeanName()方法传递Bean的ID。(和下面的一条均属于检查Aware接口)
  • 如果Bean实现了BeanFactoryAware接口,工厂调用setBeanFactory()方法传入工厂自身
  • 将Bean实例传递给Bean的前置处理器的postProcessBeforeInitialization(Object bean, String beanname)方法
  • 调用Bean的初始化方法
  • 将Bean实例传递给Bean的后置处理器的postProcessAfterInitialization(Object bean, String beanname)方法
  • 使用Bean
  • 容器关闭之前,调用Bean的销毁方法
    BeanNameAware和BeanFactoryAware是为了让Spring立即处理工厂中所有Bean的定义,并且将这些Bean全部实例化。因为Spring默认实例化Bean的情况下,采用的是lazy机制,换言之,如果不通过getBean()方法(BeanFactory或者ApplicationContext的方法)获取Bean的话,那么为了节省内存将不实例话Bean,只有在Bean被调用的时候才实例化他们。
    在这里插入图片描述
    Spring的内部bean
    当一个bean被用作另一个bean的属性时,这个bean可以被声明为内部bean。在基于
    XML的配置元数据中,可以通过把元素定义在 或元素内部实现定义内部bean。内部
    bean总是匿名的并且它们的scope总是prototype。

bean自动装配

Spring容器可以自动配置相互协作beans之间的关联关系。这意味着Spring可以自动
配置一个bean和其他协作bean之间的关系,通过检查BeanFactory 的内容里没有使
用和< property>元素。
自动装配的各种模式
自动装配提供五种不同的模式供Spring容器用来自动装配beans之间的依赖注入:
no:默认的方式是不进行自动装配,通过手工设置ref 属性来进行装配bean。
byName:通过参数名自动装配,Spring容器查找beans的属性,这些beans在XML
配置文件中被设置为byName。之后容器试图匹配、装配和该bean的属性具有相同名
字的bean。
byType:通过参数的数据类型自动自动装配,Spring容器查找beans的属性,这些
beans在XML配置文件中被设置为byType。之后容器试图匹配和装配和该bean的属
性类型一样的bean。如果有多个bean符合条件,则抛出错误。
constructor:这个同byType类似,不过是应用于构造函数的参数。如果在
BeanFactory中不是恰好有一个bean与构造函数参数相同类型,则抛出一个严重的错
误。
autodetect:如果有默认的构造方法,通过 construct的方式自动装配,否则使用
byType的方式自动装配。
自动装配有哪些局限性
重写:你仍然需要使用 和< property>设置指明依赖,这意味着总要重写自动装配。
原生数据类型:你不能自动装配简单的属性,如原生类型、字符串和类。
模糊特性:自动装配总是没有自定义装配精确,因此,如果可能尽量使用自定义装
配。

51.解释AOP
面向切面编程,或AOP允许程序员模块化横向业务逻辑,或定义核心部分的功能,例如
日志管理和事务管理。

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

AOP的局限性

通常在代码中使用AOP,只在小规模的应用中可行,一旦面向大规模应用,许多问题就会接踵而来。
  
  除此之外,面向方面的开发过程还必须解决很多的具体问题,诸如:
  
  怎样在切入点的公共模式与切入点的特征描述之间权衡?这是一个怎样合理的控制AOP的粒度的问题,前面我们已经提到过,横切关注点的粒度其实是很难决定的。在高层次上定义的横切关注点, 在底层实现的时候还可能会碰到问题。对具体的AOP实现,可能单纯从代码的角度来看,粒度划分得越细越简单越好。但这样一来,方面的代码与核心代码就会绑定很死,不好维护。而且方面的代码不优雅,看起来好像单纯把一块代码摘出来另放一个地方,刻意隐藏的痕迹很重,很难看出AOP的好处。但粒度如果太粗,AOP的代码就必须依赖公共模式的总结,这样的公共模式首先需要花功夫来定义,力求完美,因为规则的不断变化会带来很多问题,所以应尽量避免出现规则的频繁变动。而且,规则是大家都要遵守的,这样会带来更多的编码限制。当然,对于具体的项目,编码规则的多少是具体的问题,但如何能做到适度,并不是一个简单的问题。
  
  很现实的一个问题,如果在大型开发项目有多个横切关注点的时候,这些关注点之间应该如何打交道。在我们的实际项目中,就遇到这样一个难题,日志关注点在很多情况下是与其他横切关注点纠缠在一起的。其中的难题是横切关注点的剥离先后顺序问题。在一个版本延续性的开放项目中,由于需要重构,这个问题更为突出。某些情况下,横切关注点之间如果存在双向的相互依赖,就必须要修改逻辑,屏蔽这种可能性,否则,以目前的AOP的实现方式,很难处理,AOP的代码会很难看,主逻辑的代码重构会纷繁琐碎,而且极难维护。
  
  在一个大型的软件开发项目中,软件的生命周期应该都处于可管理的状态。如果AOP大规模介入,很多问题都变得很敏感,尤其是QA。按照AOP的想法,关注点是互相隔离开的,因此,实质上AOP造成软件模块间的耦合性变得松散了。软件开发过程的松耦合必然带来测试的复杂性。如果系统中的关注点控制在小范围,那么这种负担可以在小范围的开发单位内部消化掉,但一旦关注点涉及到全局,这种变动就会蔓延,带来的测试和QA的额外工作会迅速增长。并有可能会冲击到现有的测试与QA流程
aop实例
http://blog.csdn.net/u010419967/article/details/52195853

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值