java面试题之Spring篇
1,什么是Spring?Spring优点是什么?
Spring是一个分层的JavaSE/EE full-stack(一站式)轻量级开源框架
一站式:有EE开发的每一层解决方案
WEB层:SpringMVC
Service层:Spring的Bean管理,Spring声明式事务
DAO层:Spring的JDBC模板,Spring的ORM模板
优点:
非侵入式设计:Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化。
方便解耦、简化开发:Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器的管理,大大的降低了组件之间的耦合性。
支持AOP:Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性。
支持声明式事务处理:只需要通过配置就可以完成对事物的管理,而无须手动编程。
支持多数主流框架的集成:如hibernate、mybatis、struts等
2,什么是IOC?谈谈对IOC的理解
IOC(Inversion of Control):控制反转,将对象的创建权反转(交给)Spring,Spring会根据配置文件去创建实例和管理各个实例之间的依赖关系,对象与对象之间松散
耦合,也利于功能的复用。说白了就是,IOC让对象的创建不用去new了,可以由spring自动生产,使用java的反射机制,根据配置文件在运行时动态的去创建对象以及
管理对象,并调用对象的方法。
IOC还有一种叫法:DI(Dependency Injection)依赖注入,这两个名词其实是同一个意思,要深入理解的话就是:IOC是一种设计模式,是一种思想,相当于一个容器,而
DI就好比是实现IOC的一种方式。
3,什么是AOP?谈谈对AOP的理解
AOP(Aspect Oriented Programming)面向切面编程,是OOP(面向对象编程)的延伸。
用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,同时提高了系统的可维护性。可用于权限认证、日志、事务处理。
Spring中的AOP代理离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责。AOP实现的关键在于代理模式,AOP代理主要分为静态代理和动态代理。静态代理的代表为AspectJ;动态代理则以Spring AOP为代表。AspectJ是静态代理的增强,也被称为编译时增强;Spring AOP 又被称为运行时增强。静态代理与动态代理区别在于生成AOP代理对象的时机不同,相对来说AspectJ的静态代理方式具有更好的性能,但是AspectJ需要特定的编译器进行处理,而Spring AOP则无需特定的编译器处理。
Spring AOP中的动态代理主要有两种方式,JDK动态代理和CGLIB动态代理:JDK动态代理只提供接口的代理,不支持类的代理。核心InvocationHandler接口和Proxy类,InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起;接着,Proxy利用 InvocationHandler动态创建一个符合某一接口的的实例, 生成目标类的代理对象。
4,什么是Spring Bean?SpringBean的生命周期?SpringBean的作用域?
Spring Bean就是被Spring IOC容器初始化,装配和管理的Java对象。
Bean的生命周期:
总体上来看可分为四个阶段:实例化 -> 属性赋值 -> 初始化 -> 销毁
我们一个一个阶段来看:
(1)实例化之前,Bean会调用InstantiationAwareBeanPostProcessor接口(BeanPostProcessor接口的子接口,下面初始化阶段会提到)
中的postProcessBeforeInstantiation()方法
(2)实例化阶段:调用createBeanInstance()方法;
(3)实例化之后,调用InstantiationAwareBeanPostProcessor接口中的postProcessAfterInstantiation()方法
(4)属性赋值阶段:调用populateBean()方法;
(5)初始化之前:调用Aware类型的接口(例如:BeanNameAware、BeanFactoryAware)中的方法,这些接口的作用就是去拿到Spring
容器的资源;除此之外,还会调用BeanPostProcessor接口中的postProcessBeforeInitialization()方法。
(6)初始化阶段:调用initializeBean()方法;如果Bean在Spring配置文件中配置了 init-method 属性,则会自动调用其配置的初始化方法。
(7)初始化之后:会调用BeanPostProcessor接口中的postProcessAfterInitialization()方法
(8)销毁阶段:调用DisposableBean接口中的destroy()方法;如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用
其配置的销毁方法。
作用域(5个):
singleton:默认的,单例模式,只会创建一个实例对象,多个变量只会指向这唯一一个对象
prototype:多例模式,每调用一次getBean方法就会创建一个实例对象
request:应用于web项目,Spring创建这个类以后,将这个类存入到request范围中
session:应用于web项目,Spring创建这个类以后,将这个类存入到session范围中
globalsession:应用于web项目,必须在porlet环境下使用,如果没有这种环境,相对于session
5,Spring的自动装配有哪些?
参考:https://www.jianshu.com/p/2f1c9fad1d2d
6,BeanFactory和ApplicationContext有什么区别?
BeanFactory和ApplicationContext是Spring的两大核心接口,都可以当做Spring的容器。其中ApplicationContext是BeanFactory的子接口。
BeanFactory是Spring中最底层的接口,ApplicationContext接口作为BeanFactory的派生,除了提供BeanFactory所具有的功能外,还提供了更完整的框架功能:
①继承MessageSource,因此支持国际化。
②统一的资源文件访问方式。
③提供在监听器中注册bean的事件。
④同时加载多个配置文件。
⑤载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。
BeanFactory只有在使用到某个Bean的时候才会去调用getBean()方法来生成类的实例,如果Bean的某一个属性没有注入,BeanFacotry加载后,直至第一次使用调用getBean方法才会抛出异常;而ApplicationContext在容器启动时,一次性创建了所有的Bean,这样我们就可以发现Spring中存在的配置错误,这样有利于检查所依赖属性是否注入。但这样的话,当配置的bean较多时,ApplicationContext 比较占内存且程序启动慢。
参考自:https://blog.csdn.net/a745233700/java/article/details/80959716
7,Spring基于xml注入依赖的方式有哪些?
set()方法注入、构造器注入、静态工厂注入、实例工厂注入
8,Spring事务管理的方式有哪些?
编程式事务管理(了解)
声明式事务管理(重点):声明式事务管理建立在AOP之上的。其本质是对方法前后进行拦截,然后在目标方法开始之前创建或者加入一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。声明式事务最大的优点就是不需要通过编程的方式管理事务,这样就不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明(或通过基于@Transactional注解的方式),便可以将事务规则应用到业务逻辑中。
9,Spring的通知类型有哪些?
Before:前置通知
AfterReturning:返回后通知,加上returning属性可以接收返回值
Around:环绕通知
AfterThrowing:异常抛出通知,throwing属性可以捕捉异常
After:最终通知