一、Spring最核心的功能是什么?使用Spring框架的最核心的原因是什么?
Spring 框架中核心组件有三个:Core、Context 和 Beans。其中最核心的组件就是Beans, Spring提供的最核心的功能就是Bean Factory。
Spring 解决了的最核心的问题就是把对象之间的依赖关系转为用配置文件来管理,也就是Spring的依赖注入机制。这个注入机制是在Ioc 容器中进行管理的。
Bean 组件是在 Spring 的 org.springframework.beans 包下。这个包主要解决了如下功能:Bean 的定义、Bean 的创建以及对 Bean 的解析。对 Spring 的使用者来说唯一需要关心的就是 Bean 的创建,其他两个由 Spring 内部机制完成。 Spring Bean 的创建采用典型的工厂模式,他的顶级接口是 BeanFactory。
BeanFactory 有三个子类:ListableBeanFactory、HierarchicalBeanFactory 和 AutowireCapableBeanFactory。但是从上图中我们可以发现最终的默认实现类是 DefaultListableBeanFactory,他实现了所有的接口。那为何要定义这么多层次的接口呢?查阅这些接口的源码和说明发现,每个接口都有他使用的场合,它主要是为了区分在 Spring 内部在操作过程中对象的传递和转化过程中,对对象的数据访问所做的限制。例如 ListableBeanFactory 接口表示这些 Bean 是可列表的,而 HierarchicalBeanFactory 表示的是这些 Bean 是有继承关系的,也就是每个 Bean 有可能有父 Bean。AutowireCapableBeanFactory 接口定义 Bean 的自动装配规则。这四个接口共同定义了 Bean 的集合、Bean 之间的关系、以及 Bean 行为。
Bean 的定义就是完整的描述了在 Spring 的配置文件中你定义的 <bean/> 节点中所有的信息,包括各种子节点。当 Spring 成功解析你定义的一个 <bean/> 节点后,在 Spring 的内部他就被转化成 BeanDefinition 对象。以后所有的操作都是对这个对象完成的。Bean 的解析过程非常复杂,功能被分的很细,因为这里需要被扩展的地方很多,必须保证有足够的灵活性,以应对可能的变化。Bean 的解析主要就是对 Spring 配置文件的解析。
二、Spring框架分为哪七大模块,各模块的主要功能作用是什么?
七大模块,如下:
1. Spring Core: Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
2.Spring Context: 构建于Core封装包基础上的 Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。
3.Spring DAO: DAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。
4.Spring ORM: ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPA、JDO、Hibernate 和 iBatis 。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。
5.Spring AOP: Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。
6.Spring Web: Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。
7.Spring Web MVC: Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。
三、Spring框架中的三大核心思想是什么?
DI(依赖注入),IOC(控制反转),AOP(面向切面编程)
四、IOC的概念以及在Spring容器中如何进行IOC的操作。
IOC:Inversion of Control,控制反转。在Java开发中,IOC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制,这称为控制反转,就是被调用类的实例由原先的调用类控制创建、销毁现在转变成由Spring的容器管理。
五、Spring容器是如何管理Bean的生命周期的(如Bean的初始化方法,Bean的销毁方法)
创建:<bean name=”” class=”” 额外属性>
初始化:配置init-method/实现接口InitializingBean
调用:context.getBean(),进行方法的调用
销毁:配置destroy-method/实现DisposableBean接口
六、DI的概念以及在Spring框架注入有几种方式。使用构造注入对象,必须要注意什么问题,当设值注入与构造注入同时存在时,执行的先后流程顺序
注入方式:
- 接口注入
- 属性注入[属性的SET/GET]
- 构造注入[构造方法注入]
使用构造函数依赖注入时,Spring保证所有一个对象所有依赖的对象先实例化后,才实例化这个对象。使用set方法依赖注入时,Spring首先实例化对象,然后才实例化所有依赖的对象。
当设值注入与构造注入同时存在时,先执行设置注入,在执行构造注入。
七、使用DI注入时,Property代表什么意思,如果property引用的是其他Bean的话,如何注入,如果引用是字符串的话,如何设置。
使用DI注入时,Property代表注入类的属性,如果应用其他的bean用ref属性来表明被引用bean的名称,如果是引用字符串的话,用value属性。如:
<property name=”userDao” ref=”被引用bean的名称” />
<property name=”username” value = “字符串”/>
八、Spring AOP相关的几道面试题
1. 说出Spring的通知类型有哪些?
2. 谈谈目标对象实现接口与目标对象不实现接口有什么区别?
3. 请描述JDK动态代理和CGLI代理的区别?
4. 简述ProxyFactoryBean的作用是什么?
5. 叙述Spring中的自动代理的原理?
5. 写出创建代理对象需指定的三要素是什么?
6. 写出代理的两种方式分别是什么?
7. 请简述:什么是AOP?
8. 简述AOP核心?
9. 请叙述AOP事务的含义?
九、Sping IOC相关的问题
1. 请简述Spring的工作机制?
2. 请回答你为什么用Spring的工作机制?
3. 请简述Spring是什么?
4. 简述spring的组成?
5.简述Spring容器提供了哪些功能?
6. 在Spring中,bean的注入有几种方式,各是什么?
7. 请简述:Spring bean的作用域?
8. 请叙述设值注入的优点?
9. 请叙述构造注入的优点?
10. 说出bean工厂创建bean的三种方式?
11. 请写出bean的生命周期的方法?
12. 请简述你对IOC的理解?
13. 请回答:IoC最大的好处是什么?
14. 简述IoC的类型?
15. Spring中依赖注入与传统编程之间的差别是什么?
- IOC的概念以及在Spring容器中如何进行IOC的操作。
- Spring容器是如何管理Bean的生命周期的(如Bean的初始化方法,Bean的销毁方法)
- DI的概念以及在Spring框架注入有几种方式。使用构造注入对象,必须要注意什么问题,当设值注入与构造注入同时存在时,执行的先后流程顺序
- 使用DI注入时,Property代表什么意思,如果property引用的是其他Bean的话,如何注入,如果引用是字符串的话,如何设置。
- 在Spring框架中获取连接池有几种方式。当JNDI与DBCP同时存在时,会不会出现问题,如果不能同时存在的话,请说明原因
- 在使用Spring的JDBCTemplate操作数据时,必须要往模板中注入哪些对象,同时模板要不要手动关闭数据库连接
- JdbcTemplate的QueryForList方法得到List集合,请问List集合中每一个对象为什么数据类型,在JSP页面使用EL表达式如何取值。
- AOP的概念以及使用AOP机制有什么好处。Java编程中实现AOP有几种方式
- Spring框架中的事务处理有几种。请分别阐述两者的区别
- 编程式事务的总接口是什么?使用编程式事务需要用到哪几个Spring事务的核心类对象
- Spring的声明式事务能不能为普通的类产生代理接口,能不能在代码中使用Try/Catch能捕获异常,如果不可以,请说明原因
- 使用TransactionProxyFactoryBean为Bean产生事务物理时,需要哪几个属性值的设置
1、 简述你对IoC(Inversion of Control)的理解,描述一下Spring中实现DI(Dependency Injection)的几种方式。
2、Spring提倡面向接口编程,请讲一下你对它的理解,它有什么好处。
3、Spring的Bean有哪些作用域。
4、简单描述Spring Framework与Struts的不同之处,整合Spring与Struts有哪些方法,哪种最好,为什么?
5、Rails中大量使用Convention over Configuration的思想,SpringMVC在2.0后也引入了CoC,请简单描述一下SpringMVC的CoC。
6、Hibernate中的update()和saveOrUpdate()的区别,session的load()和get()的区别。
7、Spring对多种ORM框架提供了很好的支持,简单描述在Spring中使用Hibernate的方法,并结合事务管理。
8、简述Spring的事务传播行为和隔离级别。
答案:
1、好莱坞原则——不要打电话找我,我会打给你的。IoC将创建的职责从应用程序代码搬到了框架中。Spring对Setter注入和构造方法注入提供支持。(详见http://martinfowler.com/articles/injection.html,以及http://www.redsaga.com/spring_ref/2.0/html/beans.html#beans-factory-collaborators)
2、在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的对系统设计人员来讲就不那么重要了;而各个对象之间的协作关系则成为系统设计的关键。小到不同类之间的通信,大到各模块之间的交互,在系统设计之初都是要着重考虑的,这也是系统设计的主要工作内容。(详见http://deve.blogdriver.com/deve/415943.html)
3、singleton、prototype、request、session、global session、自定义(详见Spring Framework 2.0 Reference的3.4节bean的作用域)
4、Spring是完整的一站式框架,而Struts仅是MVC框架,且着重于MVC中的C。Spring有三种方式整合Struts:使用 Spring 的 ActionSupport 类整合 Struts;使用 Spring 的 DelegatingRequestProcessor 覆盖 Struts 的 RequestProcessor;将 Struts Action 管理委托给 Spring 框架,动作委托最好。(详见使用Spring 更好地处理Struts 动作)
Spring 2.0新增一种方式:AutowiringRequestProcessor。(详见http://www.javaeye.com/topic/24239)
5、控制器Bean以Controller结尾可直接映射为地址,模型ModelAndView可以不用指定键名,可根据URL自动取得视图名。(详见Spring Framework 2.0 Reference的13.11节惯例优先原则)
6、saveOrUpdate()方法可以实现update()的功能,但会多些步骤,具体如下:
如果对象在该session中已经被持久化,不进行操作;
对象的标识符属性(identifier property)在数据库中不存在或者是个暂时的值,调用save()方法保存它;
如果session中的另一个对象有相同的标识符抛出一个异常;
以上皆不符合则调用update()更新之。
Session.load/get方法均可以根据指定的实体类和id从数据库读取记录,并返回与之对应的实体对象。其区别在于:
如果未能发现符合条件的记录,get方法返回null,而load方法会抛出一个ObjectNotFoundException;
load方法可返回实体的代理类实例,而get方法永远直接返回实体类;
load方法可以充分利用内部缓存和二级缓存中的现有数据,而get方法则仅仅在内部缓存中进行数据查找,如没有发现对应数据,将越过二级缓存,直接调用SQL完成数据读取。
7、在context中定义DataSource,创建SessionFactoy,设置参数;DAO类继承HibernateDaoSupport,实现具体接口,从中获得HibernateTemplate进行具体操作。在使用中如果遇到OpenSessionInView的问题,可以添加OpenSessionInViewFilter或OpenSessionInViewInterceptor。(详见Spring Framework 2.0 Reference的12.2节Hibernate)
声明式事务需声明事务管理器,在context中设置<tx:advice>指定属性,用<aop:config>确定<aop:advisor>和<aop:pointcut>。(详见Spring Framework 2.0 Reference的9.5节声明式事务管理)
8、传播行为分为六种:
PROPAGATION_REQUIRED–支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS–支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY–支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW–新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED–以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER–以非事务方式执行,如果当前存在事务,则抛出异常。
隔离级别:
ISOLATION_DEFAULT 这是一个PlatfromTransactionManager默认的隔离级别,使用数据库默认的事务隔离级别.另外四个与JDBC的隔离级别相对应
ISOLATION_READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻像读。
ISOLATION_READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。另外一个事务不能读取该事务未提交的数据。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻像读。
ISOLATION_REPEATABLE_READ 这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻像读。它除了保证一个事务不能读取另一个事务未提交的数据外,还保证了避免下面的情况产生(不可重复读)。
ISOLATION_SERIALIZABLE 这是花费最高代价但是最可靠的事务隔离级别。事务被处理为顺序执行。除了防止脏读,不可重复读外,还避免了幻像读。