Java面试题-Spring(持续更新)

什么是Spring?

  1. Spring的核心是一个轻量级(Lightweight)的容器(Container)。
  2. Spring是实现IoC(Inversion of Control)容器和非入侵性(No intrusive)的框架。
  3. Spring提供AOP(Aspect-oriented programming)概念的实现方式。
  4. Spring提供对持久层(Persistence)、事物(Transcation)的支持。
  5. Spring供MVC Web框架的实现,并对一些常用的企业服务API(Application Interface)提供一致的模型封装。
  6. Spring提供了对现存的各种框架(Structs、JSF、Hibernate、Ibatis、Webwork等)相整合的方案。

什么是IOC、DI?

       Ioc—Inversion of Control,即“控制反转”,不是什么技术,而是一种设计思想,Spring的核心。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。
  Java中的Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。
  IoC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象。这一点是通过DI(Dependency Injection,依赖注入)来实现的。
  DI—Dependency Injection,即“依赖注入”:组件之间依赖关系由容器在运行期决定,形象的说,即由容器动态的将某个依赖关系注入到组件之中。依赖注入的目的并非为软件系统带来更多功能,而是为了提升组件重用的频率,并为系统搭建一个灵活、可扩展的平台。
  那么DI是如何实现的呢?
  Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。
  IOC容器的初始化过程
  资源定位,即定义bean的xml-------》载入--------》IOC容器注册,注册beanDefinition
  IOC容器的初始化过程,一般不包含bean的依赖注入的实现,在spring IOC设计中,bean的注册和依赖注入是两个过程,,依赖注入一般发生在应用第一次索取bean的时候,但是也可以在xm中配置,在容器初始化的时候,这个bean就完成了初始化。
  三种注入方式,构造器、接口、set注入,我们常用的是set注入
       bean是如何创建:工厂模式

AOP

       面向切面编程是对面向对象编程(oop)的补充

AOP 框架具有的两个特征

       各个步骤之间的良好隔离性 ;
       源代码无关性 。

AOP的实现原理

       代理

AOP 主要功能

       日志记录,性能统计,安全控制,事务处理,异常处理等等。

AOP 主要意图

       将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

什么是SpringMvc?

       是基于Spring的MVC框架。

Spring初始化流程

  1. Spring web应用,部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的Spring IoC容器提供宿主环境
  2. 在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件
  3. 此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,
  4. WebApplicationContext是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定。
  5. 在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,便于获取
  6. contextLoaderListener监听器初始化完毕后,开始初始化web.xml中配置的Servlet,这个servlet可以配置多个,以最常见的DispatcherServlet为例。
  7. DispatcherServlet实际上是一个标准的前端控制器,用以转发、匹配、处理每个servlet请求。DispatcherServlet上下文在初始化的时候会建立自己的IoC上下文,用以持有Spring mvc相关的bean。
  8. DispatcherServlet默认使用WebApplicationContext(ContextLoaderListener初始化产生)中的ServletContext中获取之前的根上下文
  9. 有了这个根上下文之后,再初始化自己持有的上下文。这个DispatcherServlet初始化自己上下文的工作在其initStrategies方法中可以看到,大概的工作就是初始化处理器映射、视图解析等。
  10. 这个servlet自己持有的上下文默认实现类也是xmlWebApplicationContext。初始化完毕后,spring以与servlet的名字相关(此处不是简单的以servlet名为Key)的属性为属性Key,也将其存到ServletContext中,以便后续使用。
  11. 这样每个servlet就持有自己的上下文,即拥有自己独立的bean空间,同时各个servlet共享相同的bean,即根上下文(第2步中初始化的上下文)定义的那些bean。

SpringMvc整个的执行流程

       前端控制器:DispatcherServlet
       处理器映射器:HandlerMapping
       处理器适配器:HandlerAdapter

  1. 发起请求到前端控制器(DispatcherServlet );
  2. DispatcherServlet 请求 HandlerMapping查找Handler(可以根据xml、注解进行查找);
  3. HandlerMapping 向前 DispatcherServlet返回Handler;
  4. DispatcherServlet 调用 HandlerAdapter 执行Handler;
  5. HandlerAdapter 执行 Handler;
  6. Handler执行完给处理器适配器返回ModelAndView;
  7. 处理器适配器向前端控制器返回ModelAndView (ModelAndView 是SpringMvc的底层对象包括model和view);
  8. 前端控制器请求视图解析器去解析视图,根据逻辑视图名解析成真正的视图(jsp);
  9. 前端控制器进行视图渲染

SpringMvc 和Struts2区别

       Struts2是类级别的拦截, 一个类对应一个request上下文,SpringMVC是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上SpringMVC就容易实现restful url,而struts2的架构实现起来要费劲,因为Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。
  由上边原因,SpringMVC的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架,方法之间不共享变量,而Struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码 读程序时带来麻烦,每次来了请求就创建一个Action,一个Action对象对应一个request上下文。
  由于Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。
   拦截器实现机制上,Struts2有以自己的interceptor机制,SpringMVC用的是独立的AOP方式,这样导致Struts2的配置文件量还是比SpringMVC大。
  SpringMVC的入口是servlet,而Struts2是filter(这里要指出,filter和servlet是不同的。以前认为filter是servlet的一种特殊),这就导致了二者的机制不同,这里就牵涉到servlet和filter的区别了。
  SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。
  SpringMVC验证支持JSR303,处理起来相对更加灵活方便,而Struts2验证比较繁琐,感觉太烦乱。
  spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。
   设计思想上,Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。
  SpringMVC开发效率和性能高于Struts2。
  SpringMVC可以认为已经100%零配置。
##如果1个接口有2个不同的实现, 那么怎么来Autowire指定某一个实现?
  @Qualifier(“ServiceName”)
  qualifier的意思是合格者,通过这个标示,表明了哪个实现类才是我们所需要的,我们修改调用代码,添加@Qualifier注解,需要注意的是@Qualifier的参数名称必须为我们之前定义@Service注解的名称之一!
##Spring的声明式事务 @Transaction注解一般写在什么位置? 抛出了异常会启动回滚吗?有没有办法控制不触发回滚?
   @Transactional 可以作用于接口、接口方法、类以及类方法上。当作用于类上时,该类的所有 public 方法将都具有该类型的事务属性,同时,我们也可以在方法级别使用该标注来覆盖类级别的定义。
  @Transactional 注解可以作用于接口、接口方法、类以及类方法上,但是 Spring 建议不要在接口或者接口方法上使用该注解,因为这只有在使用基于接口的代理时它才会生效。
  另外, @Transactional 注解应该只被应用到 public 方法上,这是由 Spring AOP 的本质决定的。如果你在 protected、private 或者默认可见性的方法上使用 @Transactional 注解,这将被忽略,也不会抛出任何异常。

@autowired 与new 区别

       new出来的对象无法调用@Autowired注入的Spring Bean,否则报空指针异常。
  @Autowired注入Spring Bean,则当前类必须也是Spring Bean才能调用它,不能用new xxx()来获得对象,这种方式获得的对象无法调用@Autowired注入的Bean。

Bean的默认作用范围是什么?其他的作用范围?

spring容器中的bean可以分为5个范围。

  1. singleton:这种bean范围是默认的,这种范围确保不管接受到多少个请求,每个容器中只有一个bean的实例,单例的模式由bean factory自身来维护。
  2. prototype:原形范围与单例范围相反,为每一个bean请求提供一个实例。
  3. request:在请求bean范围内会每一个来自客户端的网络请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。
  4. Session:与请求范围类似,确保每个session中有一个bean的实例,在session过期后,bean会随之失效。
  5. global-session:global-session和Portlet应用相关。当你的应用部署在Portlet容器中工作时,它包含很多portlet。如果你想要声明让所有的portlet共用全局的存储变量的话,那么这全局变量需要存储在global-session中。

Spring中的单例bean的线程安全问题了解吗?

  大部分时候我们并没有在系统中使用多线程,所以很少有人会关注这个问题。单例bean存在线程问题,主要是因为当多个线程操作同一个对象的时候,对这个对象的非静态成员变量的写操作会存在线程安全问题。
  有两种常见的解决方案:
  1在bean对象中尽量避免定义可变的成员变量(不太现实)。
  在类中定义一个ThreadLocal成员变量,将需要的可变成员变量保存在ThreadLocal中(推荐的一种方式)
原文来自:lyhkmm.com

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值