IOC、AOP、AOP原理动态代理和cglib原理与二者之间的区别、Bean 生命周期、ThreadLocal 保证线程安全、事务传播、Spring MVC、设计模式,除了这些面试题经常出现的,还有就是需要看一些Spring源码解读,因为一些面试官会问你,有没有看过源码,这时候把自己看过的看懂的说一下就OK了。
MVC
M:指的是模型,控制器在完成逻辑处理后,通常会产生一些信息,这些信息需要返回给用户并在浏览器上显示,这些信息被称为模型(model)
V:模型需要以用户友好的方式进行格式化,一般会是HTML,所以信息需要发送给一个视图(view)通常会是JSP。
C:控制器,控制器是一个用于处理请求的Spring组件。在典型的应用程序中可能会有多个控制器。
解释一下ApplicationContext
Spring有两个核心接口,BeanFactory 和 ApplicationContext,其中ApplicationContext是BeanFactory的子接口。他们都能代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的bean。Spring容器最基本的接口就是BeanFactory。BeanFactory负责配置、创建、管理Bean,他有一个子接口:ApplicationContext,因此也称之为Spring上下文。Spring容器负责管理Bean与Bean之间的依赖关系。
ApplicationContext通常的实现是什么?
-
FileSystemXmlApplicationContext :此容器从一个XML文件中加载beans的定义,XML Bean 配置文件的全路径名必须提供给它的构造函数。
-
ClassPathXmlApplicationContext:此容器也从一个XML文件中加载beans的定义,这里,你需要正确设置classpath因为这个容器将在classpath里找bean配置。
-
WebXmlApplicationContext:此容器加载一个XML文件,此文件定义了一个WEB应用的所有bean。
解释一下AOP
AOP是面向切面编程技术,通过这种技术,可以实现横切关注点与它们所影响的对象之间的解耦。切面提供了一种方案,这种方案可以在一个地方定义通用功能,但是可以通过声明的方式定义这个功能要以何种方式在何处使用,而无需修改受影响的类。横切关注点可以被模块化为特殊的类,这些类被称为切面,这样做有两个好处,首先,现在每个关注点都集中于一个地方,而不是分散到多处代码中,其次,服务模块更加简洁,因为他们只需要包含主要关注点(核心功能)的代码,而次要需要关注的代码被转移到切面中了。
AOP是基于动态代理的。如果要代理的对象,实现了某个接口,那么Spring AOP会使用JDK Proxy,去创建代理对象,而对于没有实现接口的对象,就无法使用 JDK Proxy 去进行代理了,这时候Spring AOP会使用Cglib ,这时候Spring AOP会使用 Cglib 生成一个被代理对象的子类来作为代理
AOP术语
通知:定义了切面是什么以及何时使用
连接点:应用可能有数以千计的时机应用通知,这些时机被称为连接点。连接点是在应用执行过程中能够插入切面的一个点。
切点:切点有助于缩小切面所通知的连接点的范围。如果说通知定义了切面的“什么”和“何时”的话,切点就定义了“何处”。
切面:切面是通知和切点的结合,通知和切点共同定义了切面的全部内容——他是什么?在何时和何处完成其功能。
引入:引入允许我们向现有的类添加新方法或属性。
织入:织入是把切面应用到目标对象并创建新的代理对象的过程。切面在指定的连接点被织入到目标对象中。
通知的种类
- 前置通知:在目标方法被调用之前调用通知功能
- 后置通知:在目标方法完成之后调用通知,此时不会关心方法的输出是什么
- 返回通知:在目标方法成功执行之后调用通知
- 异常通知:在目标方法抛出异常后调用通知
- 环绕通知:通知包裹了被通知的方法,再被通知的方法调用之前和之后执行自定义的行为。
解释一下IoC
IoC(Inverse of Control)控制反转是一种设计思想,就是将原本在程序中手动创建对象的控制权,交由Spring框架来管理。IoC在其他语言中也有应用,并非Spring特有,IOC容器是Spring用来实现IOC的载体,IOC容器实际就是一个Map,Map中存放的是各种对象。使用IOC的好处:第一,资源集中管理,实现资源的可配置和易管理。第二,降低了使用资源双方的依赖程度,也就是我们说的耦合度。
原理:工厂模式+反射
Java中实现注入的几种方式
- 构造器注入
- Setter方法注入
- 接口注入
Spring中注入的方式
- 构造器注入
- setter方法注入
Spring中bean的作用域
- Singleton(缺省)不管有多少个请求,每个容器中只有一个bean的实例。
- Prototype 原型实例,为每一个bean请求提供一个实例
- request 在请求bean范围内会给每一个来自客户端的网络请求创建一个实例,在请求完成之后,bean会失效并被垃圾回收器回收。
- Session 与请求范围类似,确保每个session中有一个bean的实例,在session过期之后,bean会随之失效。
- global-session
IoC和DI的区别
IoC控制反转,指将对象的创建权,反转到Spring容器,DI依赖注入,指的是Spring在创建对象的过程中,讲对象依赖属性通过配置进行注入。
Spring中bean是线程安全的吗?如果不是如何保证线程安全?
Spring中的bean不是线程安全的。
如果要保证线程安全,可以使用ThreadLocal解决。我们知道在一般情况下,只有无状态的Bean才可以在多线程环境下共享,在Spring中,绝大部分Bean都可以声明为singleton作用域。就是因为Spring对一些Bean(如RequestContextHolder、TransactionSynchronizationManager、LocaleContextHolder等)中非线程安全状态采用ThreadLocal进行处理,让它们也成为线程安全的状态,因为有状态的Bean就可以在多线程中共享了。
ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。
在同步机制中,通过对象的锁机制保证同一时间只有一个线程访问变量。这时该变量是多个线程共享的,使用同步机制要求程序慎密地分析什么时候对变量进行读写,什么时候需要锁定某个对象,什么时候释放对象锁等繁杂的问题,程序设计和编写难度相对较大。
而ThreadLocal则从另一个角度来解决多线程的并发访问。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。ThreadLocal提供了线程安全的共享对象,在编写多线程代码时,可以把不安全的变量封装进ThreadLocal。
由于ThreadLocal中可以持有任何类型的对象,低版本JDK所提供的get()返回的是Object对象,需要强制类型转换。但JDK5.0通过泛型很好的解决了这个问题,在一定程度地简化ThreadLocal的使用。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
Spring中事物隔离级别
Spring事务的七种传播行为
网友评论