Spring常见面试题
# Spring 的特性和优势
非侵入式:基于 Spring 开发的应用中的对象可以不依赖于 Spring 的 API
控制反转:IOC——Inversion of Control,指的是将对象的创建权交给 Spring 去创建。
依赖注入:DI——Dependency Injection,是指依赖的对象不需要手动调用 setXX 方法去设置,而是通过配置赋值。
面向切面编程:Aspect Oriented Programming——AOP
容器:Spring 是一个容器,因为它包含并且管理应用对象的生命周期
组件化:Spring 实现了使用简单的组件配置组合成一个复杂的应用。在 Spring 中可以使用 XML 和 Java 注解组合这些对象。
一站式:在 IOC 和 AOP 的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上 Spring 自身也提供了表现层的 SpringMVC 和持久层的 Spring JDBC)
# 控制反转 (IOC)
# 配置方式
XML 配置:XML 文件
Java 配置:@Bean
注解配置:@Component,@Controller,@Service,@Repository
笔记
主流为使用 Java 配置 + 注解配置方式,Java 配置多用于第三方包,无法添加注解。
# 注入方式
- setter 方式
- 构造函数:有参构造器,入参为要注入的对象
- 注解注入:@Autowired
Spring为什么推荐构造器注入方式?
依赖不可变:使用了 final 关键字。
依赖不为空(省去了我们对其检查):由于实现了有参数的构造函数,所以不会调用默认构造函数,那么就需要 Spring 容器传入所需要的参数,所以就两种情况:1、有该类型的参数 -> 传入,OK 。2:无该类型的参数 -> 报错。
完全初始化的状态:这个可以跟上面的依赖不为空结合起来,向构造器传参之前,要确保注入的内容不为空,那么肯定要调用依赖组件的构造方法完成实例化。而在 Java 类加载实例化的过程中,构造方法是最后一步(之前如果有父类先初始化父类,然后自己的成员变量,最后才是构造方法),所以返回来的都是初始化之后的状态。
# 面向切面编程 (AOP)
AOP 最早是 AOP 联盟的组织提出的,指定的一套规范。
spring 将 AOP 的思想引入框架之中,通过 ** 预编译方式 (AspectJ) 和运行期间动态代理 (Spring AOP)** 实现程序的统一维护的一种技术。
# AspectJ
AspectJ 是一个 java 实现的 AOP 框架,它能够对 java 代码进行 AOP 编译(一般在编译期进行),让 java 代码具有 AspectJ 的 AOP 功能(当然需要特殊的编译器)
# Spring AOP
通过动态代理技术完成的;如 Java JDK 的动态代理 (Proxy,底层通过反射实现) 或者 CGLIB 的动态代理 (底层通过继承实现),Spring AOP 采用的就是基于运行时增强的代理技术。
Spring AOP与AspectJ的关系
Spring AOP 是通过动态代理实现的 AOP,而 AspectJ 是通过特殊编译器实现的 AOP,两者方向都不一样,形成互补关系,Spring AOP 更灵活,AspectJ 性能更好。基于注解的 Spring AOP 使用了 AspectJ 的注解,但实际上还是通过动态代理来实现的 AOP。