博主其他相关文章:《Java高级工程师常见面试题-总结》
1. hibernate和ibatis的区别
1.ibatis非常简单易学,hibernate相对较复杂,门槛较高。
2.二者都是比较优秀的开源产品
3.当系统属于二次开发,无法对数据库结构做到控制和修改,那ibatis的灵活性将比hibernate更适合
4.系统数据处理量巨大,性能要求极为苛刻,这往往意味着我们必须通过经过高度优化的sql语句(或存储过程)才能达到系统性能设计指标。在这种情况下ibatis会有更好的可控性和表现。
5.ibatis需要手写sql语句,也可以生成一部分,hibernate则基本上可以自动生成,偶尔会写一些hql。同样的需求,ibatis的工作量比hibernate要大很多。类似的,如果涉及到数据库字段的修改,hibernate修改的地方很少,而ibatis要把那些sql mapping的地方一一修改。
6.以数据库字段一一对应映射得到的po和hibernte这种对象化映射得到的po是截然不同的,本质区别在于这种po是扁平化的,不像hibernate映射的po是可以表达立体的对象继承,聚合等等关系的,这将会直接影响到你的整个软件系统的设计思路。
7.hibernate现在已经是主流o/r mapping框架,从文档的丰富性,产品的完善性,版本的开发速度都要强于ibatis。
2. 讲讲mybatis的连接池。
略
3. spring框架中需要引用哪些jar包,以及这些jar包的用途
略
4. springMVC的原理
5. springMVC注解的意思
略
6. spring中beanFactory和ApplicationContext的联系和区别
从上面的类结构图中可以看出来,ApplicationContext 是 BeanFactory接口的子接口。
其中BeanFactory获得配置文件的实例是:
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
HelloService helloService4 = (HelloService) beanFactory.getBean("helloService");
helloService4.sayHello();
ApplicationContext获取配置文件实例的方法是:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获得工厂实例
HelloService helloService2 = (HelloService) applicationContext.getBean("helloService"); // 通过id获得实例
//helloService2.setInfo("itcast"); // 已经配置依赖注入
helloService2.sayHello();
其实两个在代码看来就是在获取配置文件的时候 的差异,他们还有其他的差异:
1)BeanFactory 采用的是延迟加载,第一次getBean的时候才会初始化Bean
2)ApplicationContext是对BeanFactory的扩展,提供了更多的功能
结论:开发中尽量使用ApplicationContext 就可以了
7. spring注入的几种方式(循环注入)
xml配置、java配置、隐式的bean发现机制和自动装配
8. spring如何实现事物管理的
Spring事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活方便。
声明式事务管理分别使用基于TransactionProxyFactoryBean的方式、基于AspectJ的XML方式、基于注解方式进行实现。
首先,我们简单看一下Spring事务管理需要提及的接口,Spring事务管理高层抽象主要包括3个接口:
PlatformTransactionManager :事务管理器(用来管理事务,包含事务的提交,回滚)
TransactionDefinition :事务定义信息(隔离,传播,超时,只读)
TransactionStatus :事务具体运行状态
Spring根据事务定义信息(TransactionDefinition)由平台事务管理器(PlatformTransactionManager)真正进行事务的管理,在进行事务管理的过程中,事务会产生运行状态,状态保存在TransactionStatus中。
PlatformTransactionManager:
Spring为不同的持久化框架提供了不同的PlatformTransactionManager如:
在使用Spring JDBC或iBatis进行持久化数据时,采用DataSourceTransactionManager
在使用Hibernate进行持久化数据时使用HibernateTransactionManager
TransactionDefinition:
TransactionDefinition接口中定义了一组常量,包括事务的隔离级别,事务的传播行为,超时信息,其中还定义了一些方法,可获得事务的隔离级别,超时信息,是否只读。
传播行为主要解决业务层方法之间的相互调用产生的事务应该如何传递的问题。
TransactionDefinition中定义的属性常量如下:
Field(属性) |
Description(描述) |
ISOLATION_DEFAULT |
使用底层数据存储的默认隔离级别 |
ISOLATION_READ_COMMITTED |
表示防止脏读;可能会发生不可重复的读取和幻像读取 |
ISOLATION_READ_UNCOMMITTED |
表示可能会发生脏读,不可重复的读取和幻像读取 |
ISOLATION_REPEATABLE_READ |
表示禁止脏读和不可重复读;可以发生幻影读取 |
ISOLATION_SERIALIZABLE |
表示可以防止脏读,不可重复的读取和幻像读取 |
PROPAGATION_MANDATORY |
支持当前交易;如果不存在当前事务,则抛出异常 |
PROPAGATION_NESTED |
如果当前事务存在,则在嵌套事务中执行,其行为类似于PROPAGATION_REQUIRED |
PROPAGATION_NEVER |
不支持当前交易;如果当前事务存在,则抛出异常 |
PROPAGATION_NOT_SUPPORTED |
不支持当前交易;而是总是非事务地执行 |
PROPAGATION_REQUIRED |
支持当前交易;如果不存在,创建一个新的 |
PROPAGATION_REQUIRES_NEW |
创建一个新的事务,挂起当前事务(如果存在) |
PROPAGATION_SUPPORTS |
支持当前交易;如果不存在,则执行非事务性的 |
TIMEOUT_DEFAULT |
使用底层事务系统的默认超时,如果不支持超时,则为none |
TransationStatus:
在该接口中提供了一些方法:
Method |
Description |
flush() |
将基础会话刷新到数据存储(如果适用):例如,所有受影响的Hibernate / JPA会话 |
hasSavepoint() |
返回此事务是否内部携带保存点,也就是基于保存点创建为嵌套事务 |
isCompleted() |
返回此事务是否完成,即是否已经提交或回滚 |
isNewTransaction() |
返回当前交易是否是新的(否则首先参与现有交易,或者潜在地不会在实际交易中运行) |
isRollbackOnly() |
返回事务是否已被标记为仅回滚(由应用程序或由事务基础结构) |
setRollbackOnly() |
设置事务回滚 |
9. springIOC
(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。 对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另外一个名字——“依赖注入(Dependency Injection)”。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。
(2). 在Spring的工作方式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
(3). 在系统运行中,动态的向某个对象提供它所需要的其他对象。
(4). 依赖注入的思想是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。 总而言之,在传统的对象创建方式中,通常由调用者来创建被调用者的实例,而在Spring中创建被调用者的工作由Spring来完成,然后注入调用者,即所谓的依赖注入or控制反转。 注入方式有两种:依赖注入和设置注入; IoC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象。
10. spring AOP的原理
(1). AOP面向方面编程基于IoC,是对OOP的有益补充;
(2). AOP利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了 多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的 逻辑或责任封装起来,比如日志记录,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。
(3). AOP代表的是一个横向的关 系,将“对象”比作一个空心的圆柱体,其中封装的是对象的属性和行为;则面向方面编程的方法,就是将这个圆柱体以切面形式剖开,选择性的提供业务逻辑。而 剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹,但完成了效果。
(4). 实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
(5). Spring实现AOP:JDK动态代理和CGLIB代理 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理;其核心的两个类是InvocationHandler和Proxy。 CGLIB代理:实现原理类似于JDK动态代理,只是它在运行期间生成的代理对象是针对目标类扩展的子类。CGLIB是高效的代码生成包,底层是依靠ASM(开源的java字节码编辑类库)操作字节码实现的,性能比JDK强;需要引入包asm.jar和cglib.jar。 使用AspectJ注入式切面和@AspectJ注解驱动的切面实际上底层也是通过动态代理实现的。
(6). AOP使用场景:
Authentication 权限检查
Caching 缓存
Context passing 内容传递
Error handling 错误处理
Lazy loading 延迟加载
Debugging 调试
logging, tracing, profiling and monitoring 日志记录,跟踪,优化,校准
Performance optimization 性能优化,效率检查
Persistence 持久化
Resource pooling 资源池
Synchronization 同步
Transactions 事务管理
另外Filter的实现和struts2的拦截器的实现都是AOP思想的体现。
11. hibernate中的1级和2级缓存的使用方式以及区别原理(Lazy-Load的理解)
略
12. Hibernate的原理体系架构,五大核心接口,Hibernate对象的三种状态转换,事务管理。
略