框架面试题
1.Spring框架分为哪七大模块,各模块的主要功能作用是什么?
七大模块,如下: 1. Spring Core: Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
- Spring Context: 构建于Core封装包基础上的 Context 封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。
- Spring DAO: DAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。
- Spring ORM:ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括 JPA 、 JDO 、 Hibernate 和 iBatis 。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。
- Spring AOP: Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。
- Spring Web: Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。
- Spring Web MVC: Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。
2.Spring框架中的三大核心思想是什么
DI(依赖注入),IOC(控制反转),AOP(面向切面编程)
3.IOC的概念以及在Spring容器中如何进行IOC的操作。
IOC:Inversion of Control,控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器 (在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。
在Java开发中,IOC意味着将你设计好的类交给系统去控制,而不是在你的类内部控制,这称为控制反转,就是被调用类的实例由原先的调用类控制创建、销毁现在转变成由Spring的容器管理。
4.DI的概念以及在Spring框架注入有几种方式。使用构造注入对象,必须要注意什么问题,当设值注入与构造注入同时存在时,执行的先后流程顺序?
注入方式: 1. 接口注入 2. 属性注入[属性的SET/GET] 3. 构造注入[构造方法注入] 使用构造函数依赖注入时,Spring保证对象其所依赖的所有对象先实例化后,才实例化这个对象。 使用set方法依赖注入时,Spring首先实例化对象,然后才实例化所有依赖的对象。 * 当设值注入与构造注入同时存在时,先执行设置注入,在执行构造注入。
5.使用DI注入时,Property代表什么意思,如果property引用的是其他Bean的话,如何注入,如果引用是字符串的话,如何设置?
使用DI注入时,Property代表注入类的属性,如果引用其他的bean,则用ref属性来表明被引用bean的名称,如果是引用字符串的话,用value属性。
如: <property name=”userDao” ref=”被引用bean的名称” /> <property name=”username” value = ”字符串”/>
6.在使用Spring的JDBCTemplate操作数据时,必须要往模板中注入哪些对象,同时模板要不要手动关闭数据库连接
注入DataSource数据源对象,不需要手动关闭数据库连接,JdbcTemplate会帮我们关闭数据库连接
7.AOP的概念以及使用AOP机制有什么好处。Java编程中实现AOP有几种方式?
• AOP的概念是Aspected Oriented Programming 面向切面编程 >AOP将程序分解成各个切面或者说关注点。这使得可以模块化,相当横向上分切了。它可以解决OOP和过程化方法不能够很好解决的横切(crosscut)问题,如:事务、安全、日志等横切关注。
• 个人理解:如果说汇编语言是对计算机指令的抽象,面向对象语言是对程序要解决的问题的抽象,AOP则是对程序功能本身的抽象。
• 实现AOP有几种方式: >1. Spring 1.2版本中通过ProxyFactoryBean来实现aop,即通过动态代理来实现的,Aspect必须继承MethodBeforeAdvice,MethodAfterAdvice等 >2. Spring 2.0 AOP需要改的是FBI 这个类,而且它也不需要再实现某些接口 >3. 使用标注(@AspectJ)实现AOP
8.Spring框架中的事务处理有几种。请分别阐述两者的区别
spring提供的事务管理可以分为两类:编程式的和声明式的。编程式的,比较灵活,但是代码量大,存在重复的代码比较多;声明式的比编程式的更灵活.
9.Spring的声明式事务能不能为普通的类产生代理接口,能不能在代码中使用Try/Catch能捕获异常,如果不可以,请说明原因
不能。Spring的声明式事务为实现类产生代理。不能在代码中使用Try/Catch,因为代码中捕获了异常,Spring容器捕获不了异常。
10.SpringMVC的理解?SpringMVC的工作流程?
SpringMVC是基于过滤器对servlet进行了封装的一个框架,我们使用的时候就在web.xml中配置DispatcherServlet类;SpringMVC工作是主要是通过DispatcherServlet管理接受到的请求并进行处理。 * SpringMVC的工作流程描述: - 第一步:用户向服务器发送请求,请求被Spring前端控制Servelt DispatcherServlet捕获;
- 第二步: DispatcherServlet对请求URL进行解析,得到请求资源标识符(URL),然后根据该URL调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器),最后以HandlerExecutionChain对象的形式返回;
- 第三步: DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter。(附注:如果成功获得HandlerAdapter后,此时将开始执行拦截器的preHandler(…)方法)
- 第四步:提取Request中的模型数据,填充Handler入参,开始执行Handler(Controller)。 在填充Handler的入参过程中,根据你的配置,Spring将帮你做一些额外的工作: >> 1. HttpMessageConveter: 将请求消息(如Json、xml等数据)转换成一个对象,将对象转换为指定的响应信息 >> 2. 数据转换:对请求消息进行数据转换。如String转换成Integer、Double等 >> 3. 数据根式化:对请求消息进行数据格式化。 如将字符串转换成格式化数字或格式化日期 >> 4. 数据验证: 验证数据的有效性(长度、格式等),验证结果存储到BindingResult或Error中
- 第五步: Handler执行完成后,向DispatcherServlet 返回一个ModelAndView对象;
- 第六步:根据返回的ModelAndView,选择一个适合的ViewResolver(必须是已经注册到Spring容器中的ViewResolver)返回给DispatcherServlet ;
- 第七步:ViewResolver 结合Model和View,来渲染视图
- 第八步:将渲染结果返回给客户端。
11.Nginx怎么实现负载均衡?
Nginx 是俄罗斯人编写的十分轻量级的 是一个高性能的HTTP和反向代理服务器,同时也是一个 IMAP/POP3/SMTP 代理服务器. * Nginx实现负载均衡只需要在nginx文件中进行配置即可,配置如下: 1. 第一步:在http模块中配置upstream 模块:(举例)
upstream www.myweb.com { server 127.0.0.1:9100 weight=1; server 127.0.0.1:9200 weight=1;}
其中weight=1表示权重,用于后端服务器性能不均的情况,访问比率约等于权重之比,权重越大访问机会越多; upstream是配置nginx与后端服务器负载均衡非常重要的一个模块,并且它还能对后端的服务器的健康状态进行检查,若后端服务器中的一台发生故障,则前端的请求不会转发到该故障的机器;
第二步:在server模块里添加:(举例) location /myweb { proxy_pass http://www.myweb.com;} 其中 www.myweb.com 字符串要和 upstream 后面的字符串相等;
12.jsp静态包含和动态包含的区别?
• <%@ include file=”” %>是指令元素,静态包含。<jsp:include page=”” />是行为元素,动态包含。
• 最终编译成java文件的数目不同。 >1. 静态包含在转换成为java文件的时候将包含文件的内容“复制”到主体文件,然后作为一个整体编译。生成一个以包含页面命名的servlet和class文件。 >2. 动态包含是各个jsp文件分别转换,分别编译。最终编程成多个java文件。
• 执行时间不同 > 静态包含发生在:JSP生成class文件阶段。 > 动态包含发生在:执行class文件阶段。动态加入。
• 静态包含在两个文件中不能有相同的变量,动态包含允许。
• 无论是动态包含还是静态包含,其request对象都是相同的。也就是同一个request对象。
13.jsp有哪些内置对象?作用分别是什么?
• request
• response
• session
• pageContext >>javax.servlet.jsp.PageContext 的实例,对象直译时可以称作“页面上下文”对象,代表的是当前页面运行的一些属性,通过此对象可以拿到其他8大对象,使用该对象可以访问页面中的共享数据。常用的方法有getServletContextO和getServletConfigO等。
• page >>对应this关键字,JSP网页本身。page对象是当前页面转换后的Servlet类的实例。从转换后的Servlet类的代码中,可以看到这种关系:
Object page = this;
在JSP页面中,很少使用page对象。
• config >>javax.servlet. ServletConfig 的实例,该实例代表该JSP 的配置信息。常用的方法有getInitPararneter(String paramNarne) 及getInitPararneternarnes() 等方法。事实上, JSP 页面通常无须配置,也就不存在配置信息。因此,该对象更多地在Servlet 中有效。
• application >>服务器启动后就产生了这个application对象,当客户在所访问的网站的各个页面之间浏览时,这个application对象都是同一个,直到服务器关闭。但是与session不同的是,所有客户的application对象都是同一个,即所有客户共享这个内置的application对象。
• exception >>该实例代表其他页面中的异常和错误。只有当页面是错误处理页面,即编译指令page 的isErrorPage 属性为true 时,该对象才可以使用。常用的方法有getMessageO和printStackTraceO等。
• out >>out对象是一个输出流,用来向客户端输出数据。out对象用于各种数据的输出。
其中,request、response、session、application、config这五个对象和Servlet的API是一样的。
14.struts是什么?
struts1是基于JSP和servlet的一个开源的Web应用框架,使用的是MVC的设计模式。struts2是基于webwork技术的框架,是sun和webwork公司联手开发的一个功能非常齐全的框架,struts2和struts1没有任何关系,是一个全新的框架
15.JSF是什么?
JavaServer Face是基于组件的web开发框架,跟sturts差不多的框架
16.Tomcat 有哪几种Connector 运行模式(优化)?
• bio(blocking I/O):传统的Java I/O操作,同步且阻塞IO。
• nio(non-blocking I/O):JDK1.4开始支持,同步阻塞或同步非阻塞IO
• apr(Apache Portable Runtime/Apache可移植运行库):Tomcat将以JNI的形式调用Apache HTTP服务器的核心动态链接库来处理文件读取或网络传输操作,从而大大地 提高Tomcat对静态文件的处理性能
17.Hibernate中SessionFactory是线程安全的吗?Session是线程安全的吗(两个线程能够共享同一个Session吗)?
SessionFactory对应Hibernate的一个数据存储的概念,它是线程安全的,可以被多个线程并发访问。SessionFactory一般只会在启动的时候构建。对于应用程序,最好将SessionFactory通过单例模式进行封装以便于访问。Session是一个轻量级非线程安全的对象(线程间不能共享session),它表示与数据库进行交互的一个工作单元。Session是由SessionFactory创建的,在任务完成之后它会被关闭。Session是持久层服务对外提供的主要接口。Session会延迟获取数据库连接(也就是在需要的时候才会获取)。为了避免创建太多的session,可以使用ThreadLocal将session和当前线程绑定在一起,这样可以让同一个线程获得的总是同一个session。Hibernate 3中SessionFactory的getCurrentSession()方法就可以做到。
18.Hibernate中Session的load和get方法的区别是什么? - 如果没有找到符合条件的记录,get方法返回null,load方法抛出异常。
- get方法直接返回实体类对象,load方法返回实体类对象的代理。
- 在Hibernate 3之前,get方法只在一级缓存中进行数据查找,如果没有找到对应的数据则越过二级缓存,直接发出SQL语句完成数据读取;load方法则可以从二级缓存中获取数据;从Hibernate 3开始,get方法不再是对二级缓存只写不读,它也是可以访问二级缓存的。
19.Hibernate中Session的save()、update()、merge()、lock()、saveOrUpdate()和persist()方法分别是做什么的?有什么区别?
• Hibernate的对象有三种状态:瞬时态(transient)、持久态(persistent)和游离态(detached) > 1. 瞬时态的实例可以通过调用save()、persist()或者saveOrUpdate()方法变成持久态 > 2. 游离态的实例可以通过调用 update()、saveOrUpdate()、lock()或者replicate()变成持久态。 > 3. save()和persist()将会引发SQL的INSERT语句,而update()或merge()会引发UPDATE语句。save()和update()的区别在于一个是将瞬时态对象变成持久态,一个是将游离态对象变为持久态。merge()方法可以完成save()和update()方法的功能,它的意图是将新的状态合并到已有的持久化对象上或创建新的持久化对象。 > 4. persist()方法把一个瞬时态的实例持久化,但是并不保证标识符被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时间; persist()方法保证当它在一个事务外部被调用的时候并不触发一个INSERT语句,当需要封装一个长会话流程的时候,persist()方法是很有必要的;save()方法它要返回标识符,所以它会立即执行INSERT语句,不管是在事务内部还是外部。 > 5. 至于lock()方法和update()方法的区别,update()方法是把一个已经更改过的脱管状态的对象变成持久状态;lock()方法是把一个没有更改过的脱管状态的对象变成持久状态。
20.锁机制有什么用?简述Hibernate的悲观锁和乐观锁机制。
有些业务逻辑在执行过程中要求对数据进行排他性的访问,于是需要通过一些机制保证在此过程中数据被锁住不会被外界修改,这就是所谓的锁机制。 1. 悲观锁,顾名思义悲观的认为在数据处理过程中极有可能存在修改数据的并发事务(包括本系统的其他事务或来自外部系统的事务),于是将处理的数据设置为锁定状态。悲观锁必须依赖数据库本身的锁机制才能真正保证数据访问的排他性 2. 乐观锁,顾名思义,对并发事务持乐观态度(认为对数据的并发操作不会经常性的发生),通过更加宽松的锁机制来解决由于悲观锁排他性的数据访问对系统性能造成的严重影响。最常见的乐观锁是通过数据版本标识来实现的,读取数据时获得数据的版本号,更新数据时将此版本号加1,然后和数据库表对应记录的当前版本号进行比较,如果提交的数据版本号大于数据库中此记录的当前版本号则更新数据,否则认为是过期数据无法更新。 * Hibernate中通过Session的get()和load()方法从数据库中加载对象时可以通过参数指定使用悲观锁;而乐观锁可以通过给实体类加整型的版本字段再通过XML或@Version注解进行配置。
21.阐述Hibernate实体对象的三种状态以及转换关系。
• 瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区域,如果没有变量引用这个对象,则会被JVM的垃圾回收机制回收。这个对象所保存的数据与数据库没有任何关系,除非通过Session的save()、saveOrUpdate()、persist()、merge()方法把瞬时态对象与数据库关联,并把数据插入或者更新到数据库,这个对象才转换为持久态对象。
• 持久态:持久态对象的实例在数据库中有对应的记录,并拥有一个持久化标识(ID)。对持久态对象进行delete操作后,数据库中对应的记录将被删除,那么持久态对象与数据库记录不再存在对应关系,持久态对象变成移除态(可以视为瞬时态)。持久态对象被修改变更后,不会马上同步到数据库,直到数据库事务提交。
• 游离态:当Session进行了close()、clear()、evict()或flush()后,实体对象从持久态变成游离态,对象虽然拥有持久和与数据库对应记录一致的标识值,但是因为对象已经从会话中清除掉,对象不在持久化管理之内,所以处于游离态(也叫脱管态)。游离态的对象与临时状态对象是十分相似的,只是它还含有持久化标识。
22.使用Spring框架的好处是什么?
• 轻量:Spring 是轻量的,基本的版本大约2MB。
• 控制反转:Spring通过控制反转实现了松散耦合,对象们给出它们的依赖,而不是创建或查找依赖的对象们。
• 面向切面的编程(AOP):Spring支持面向切面的编程,并且把应用业务逻辑和系统服务分开。
• 容器:Spring 包含并管理应用中对象的生命周期和配置。
• MVC框架:Spring的WEB框架是个精心设计的框架,是Web框架的一个很好的替代品。
• 事务管理:Spring 提供一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)。
• 异常处理:Spring 提供方便的API把具体技术相关的异常(比如由JDBC,Hibernate or JDO抛出的)转化为一致的unchecked 异常。
23.Spring的ApplicationContext通常的实现是什么?
Application Context 是 spring 中较高级的容器。和 BeanFactory 类似,它可以加载配置文件中定义的 bean,将所有的 bean 集中在一起,当有请求的时候分配 bean。 另外,它增加了企业所需要的功能,比如,从属性文件从解析文本信息和将事件传递给所指定的监听器。这个容器在 org.springframework.context.ApplicationContext interface 接口中定义。
ApplicationContext 包含 BeanFactory 所有的功能,一般情况下,相对于 BeanFactory,ApplicationContext 会被推荐使用。BeanFactory 仍然可以在轻量级应用中使用,比如移动设备或者基于 applet 的应用程序。 - FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
- ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
- WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
24.什么是Spring beans?
Spring beans 是那些形成Spring应用的主干的java对象。它们被Spring IOC容器初始化,装配,和管理。这些beans通过容器中配置的元数据创建。比如,以XML文件中 的形式定义。
Spring 框架定义的beans都是单件beans。在bean tag中有个属性”singleton”,如果它被赋为TRUE,bean 就是单件,否则就是一个 prototype bean。默认是TRUE,所以所有在Spring框架中的beans 缺省都是单件。
25.Spring的Bean工厂和Application contexts有什么区别?
两者都是装入bean定义信息,装配bean,根据需要分发bean。但是ApplicationContext提供更多功能,它提供了bean工厂所没有的解析信息文本工具,包括对国际化的支持,提供了载入文件资源的通用方法,如载入图片,它可以用注册为监听器的bean发送事件。另外一个很重要的区别是单例bean被载入的方式不一样。bean工厂延迟载入所有的bean,直到getbean方法被调用,才被创建。而ApplicationContext会预装入所有的单例bean,确保需要的时候单例bean都已经准备好了,这样我们的应用就不需要等待这些单例bean被创建。
26.如何给Spring 容器提供配置元数据?
这里有三种重要的方法给Spring 容器提供配置元数据。 1. XML配置文件。 2. 基于注解的配置。 3. 基于java的配置。
27.解释Spring支持的几种bean的作用域。
当定义一个 在Spring里,我们还能给这个bean声明一个作用域。它可以通过bean 定义中的scope属性来定义。如,当Spring要在需要的时候每次生产一个新的bean实例,bean的scope属性被指定为prototype。另一方面,一个bean每次使用的时候必须返回同一个实例,这个bean的scope 属性 必须设为 singleton。 Spring框架支持以下五种bean的作用域: singleton : bean在每个Spring ioc 容器中只有一个实例。缺省的Spring bean 的作用域是Singleton,且Spring框架中的单例bean不是线程安全的。 prototype:一个bean的定义可以有多个实例。 request:每次http请求都会创建一个bean,该作用域仅在基于web的Spring ApplicationContext情形下有效。 session:在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。 * global-session:在一个全局的HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。
28.哪些是重要的bean生命周期方法? 你能重载它们吗?
有两个重要的bean 生命周期方法,第一个是setup , 它是在容器加载bean的时候被调用。第二个方法是 teardown 它是在容器卸载类的时候被调用。
The bean 标签有两个重要的属性(init-method和destroy-method)。用它们你可以自己定制初始化和注销方法。它们也有相应的注解(@PostConstruct和@PreDestroy)。
29.什么是Spring的内部bean?
当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义inner bean,在Spring 的 基于XML的 配置元数据中,可以在 <property/>或<constructor-arg/> 元素内使用<bean/> 元素,内部bean通常是匿名的,它们的Scope一般是prototype。 - 在 Spring中如何注入一个java集合?
Spring提供以下几种集合的配置元素: 1. <list>类型用于注入一列值,允许有相同的值。 2. < 类型用于注入一组值,不允许有相同的值。 3. < - @Required 注释应用于 bean 属性的 setter 方法,它表明受影响的 bean 属性在配置时必须放在 XML 配置文件中,否则容器就会抛出一个 BeanInitializationException 异常。
- @Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法。
- @Qualifier 注解当有多个相同类型的bean却只有一个需要自动装配时,将@Qualifier 注解和@Autowire 注解结合使用以消除这种混淆,指定需要装配的确切的bean。
36.使用Spring通过什么方式访问Hibernate?
在Spring中有两种方式访问Hibernate: 1. 控制反转 Hibernate Template和 Callback。 2. 继承 HibernateDAOSupport提供一个AOP 拦截器。
用Spring的 SessionFactory 调用 LocalSessionFactory。集成过程分三步: 1. 配置the Hibernate SessionFactory。 2. 继承HibernateDaoSupport实现一个DAO。 3. 在AOP支持的事务中装配。
37.Spring支持的事务管理类型
• 编程式事务管理:这意味你通过编程的方式管理事务,给你带来极大的灵活性,但是难维护。
• 声明式事务管理:这意味着你可以将业务代码和事务管理分离,你只需用注解和XML配置来管理事务。 >大多数Spring框架的用户选择声明式事务管理,因为它对应用代码的影响最小,因此更符合一个无侵入的轻量级容器的思想。声明式事务管理要优于编程式事务管理,虽然比编程式事务管理(这种方式允许你通过代码控制事务)少了一点灵活性。
38.什么是引入?
引入允许我们在已存在的类中增加新的方法和属性。