Spring常见面试题
问题:介绍一下 Spring?
参考答案:Spring 是一款顶级开源框架,它是包含了众多工具方法的 IoC 容器。
Spring 包含了很多模块,比如 spring-core、spring-beans、spring-aop、spring-context、spring-expression、spring-test 等,使用 Spring 可以帮我们快速的开发 Java 程序。
问题:Spring 有什么优点?
参考答案:Spring 优点如下:
- 开源免费的热门框架,稳定性高、解决问题成本低;
- 方便集成各种优秀的框架;
- 降低了代码耦合性,通过 Spring 提供的 IoC 容器,我们可以将对象之间的依赖关系交由 Spring 进行控制,避免硬编码所造成的过度程序耦合;
- 方便程序测试,在 Spring 里,测试变得非常简单,例如:Spring 对 Junit 的支持,可以通过注解方便的测试 Spring 程序;
- 降低 Java EE API 的使用难度,Spring 对很多难用的 Java EE API(如 JDBC、JavaMail、远程调用等)提供了一层封装,通过 Spring 的简易封装,让这些 Java EE API 的使用难度大为降低。
问题:什么是 IoC?
参考答案:IoC 是 Inversion of Control 的缩写,翻译成中文是”控制反转”的意思,它不是一个具体的技术,而是一个实现对象解耦的思想。
控制反转的意思是将依赖对象生命周期的控制权进行反转,传统开发是当前类控制依赖对象的生命周期的,现在交给其他人(Spring),这就是控制(权)反转。
问题:IoC 有什么优点?
参考答案:IoC 的优点有以下几个:
- 使用更方便,拿来即用,无需显式的创建和销毁的过程;
- 可以很容易提供众多服务,比如事务管理、消息服务等;
- 提供了单例模式的支持;
- 提供了 AOP 抽象,利用它很容易实现权限拦截、运行期监控等功能;
- 更符合面向对象的设计法则;
- 低侵入式设计,代码的污染极低,降低了业务对象替换的复杂性。
问题:IoC 是如何实现解耦的?
参考答案:举个例子,比如 A 对象中需要依赖 B 对象,需要调用 B 中的某个方法,我们通常的实现方法是这样的:
class A {
public void init() {
B b = new B();
b.init();
}
}
class B {
public B() {
}
public void init() {
System.out.println(“你好,世界。”);
}
}
然而此时对象 A 和对象 B 是存在耦合的,因为一旦修改了 B 对象构造方法的参数之后,那么 A 对象里面的写法也要跟着改变,比如当我们将构造方法改为以下代码时:
class B {
public B(String name) {
System.out.println(“姓名:” + name);
}
public void init() {
System.out.println(“你好,世界。”);
}
}
此时构造方法已经从原本无参构造方法变成了有参的构造方法,这里不考虑构造方法重载的情况,因为实际业务中,很可能是 B 类的构造方法写错了,忘记加参数了,于是后面又补充了一个参数,此时是不需要对构造方法进行重载的,那么此时,之前对象 A 里面的调用就会报错,如下图所示:
这就是开发中经常遇到的一个问题,那怎么解决呢?
我们可以通过将对象传递而并 new 对象的方式来解决,如下代码所示:
class A {
private B b;
public A(B b) {
this.b = b;
}
public void init() {
b.init();
}
}
class B {
public B() {
}
public B(String name) {
System.out.println(“姓名:” + name);
}
public void init() {
System.out.println(“你好,世界。”);
}
}
或者
class A {
private B b;
public void setB(B b) {
this.b = b;
}
public void init() {
b.init();
}
}
这就是解决耦合的方法,我们不需要在 A 的代码中直接 new 出 B 对象来,而是采用依赖注入的方式,将 B 对象注入到 A 中去,这样当 B 的构造方法变更之后,A 完全没有必要改变,这就是解耦的思想。
更多面试题关注公众号:程序员乔戈里