一、什么是控制反转(IOC)?什么是依赖注入?
控制反转是应用于软件工程领域中的,在运行时被装配器对象来绑定耦合对象的一种编程技巧,对象之间耦合关系在编译时通常是未知的。在传统的编程方式中,业务逻辑的流程是由应用程序中的早已被设定好关联关系的对象来决定的。在使用控制反转的情况下,业务逻辑的流程是由对象关系图来决定的,该对象关系图由装配器负责实例化,这种实现方式还可以将对象之间的关联关系的定义抽象化。而绑定的过程是通过“依赖注入”实现的。
控制反转是一种以给予应用程序中目标组件更多控制为目的设计范式,并在我们的实际工作中起到了有效的作用。
依赖注入是在编译阶段尚未知所需的功能是来自哪个的类的情况下,将其他对象所依赖的功能对象实例化的模式。这就需要一种机制用来激活相应的组件以提供特定的功能,所以依赖注入是控制反转的基础。否则如果在组件不受框架控制的情况下,框架又怎么知道要创建哪个组件?
在 Java 中依然注入有以下三种实现方式:
- 构造器注入
- Setter 方法注入
- 接口注入
二、请解释下 Spring 框架中的 IoC?
Spring 中的 org.springframework.beans
包和 org.springframework.context
包构成了 Spring 框架 IoC 容器的基础。
BeanFactory
接口提供了一个先进的配置机制,使得任何类型的对象的配置成为可能。
ApplicationContex
接口对 BeanFactory
(是一个子接口)进行了扩展,在 BeanFactory
的基础上添加了其他功能,比如与 Spring 的 AOP 更容易集成,也提供了处理 message resource
的机制(用于国际化)、事件传播以及应用层的特别配置,比如针对 Web 应用的 WebApplicationContext
。
org.springframework.beans.factory.BeanFactory
是 Spring IoC 容器的具体实现,用来包装和管理前面提到的各种 bean。BeanFactory
接口是 Spring IoC 容器的核心接口。
IOC
:把对象的创建、初始化、销毁交给 spring 来管理,而不是由开发者控制,实现控制反转。
三、BeanFactory 和 ApplicationContext 有什么区别?
BeanFactory
可以理解为含有 bean 集合的工厂类。BeanFactory
包含了种 bean 的定义,以便在接收到客户端请求时将对应的 bean 实例化。
BeanFactory
还能在实例化对象的时生成协作类之间的关系。此举将 bean 自身与 bean 客户端的配置中解放出来。BeanFactory
还包含 了 bean 生命周期的控制,调用客户端的初始化方法(initialization methods
)和销毁方法(destruction methods
)。
从表面上看,application context
如同 bean factory
一样具有 bean 定义、bean 关联关系的设置,根据请求分发 bean 的功能。但 applicationcontext
在此基础上还提供了其他的功能。
- 提供了支持国际化的文本消息
- 统一的资源文件读取方式
- 已在监听器中注册的 bean 的事件
以下是三种较常见的 ApplicationContext
实现方式:
-
ClassPathXmlApplicationContext
:从classpath
的 XML 配置文件中读取上下文,并生成上下文定义。应用程序上下文从程序环境变量中
ApplicationContext context = new ClassPathXmlApplicationContext(“bean.xml”);
-
FileSystemXmlApplicationContext
:由文件系统中的 XML 配置文件读取上下文。
ApplicationContext context = new FileSystemXmlApplicationContext(“bean.xml”);
-
XmlWebApplicationContext
:由 Web 应用的 XML 文件读取上下文。 -
AnnotationConfigApplicationContext
(基于 Java 配置启动容器)
本文仅供参考!
文章内容节选自《Spring面试专题及答案》需要的同学记得私信我免费获取!
四、Spring 有几种配置方式?
将 Spring 配置到应用开发中有以下三种方式:
- 基于 XML 的配置
- 基于注解的配置
- 基于 Java 的配置
五、请解释 Spring Bean 的生命周期?
Spring Bean
的生命周期简单易懂。在一个 bean 实例被初始化时,需要执行一系列的初始化操作以达到可用的状态。同样的,当一个 bean 不在被调用时需要进行相关的析构操作,并从 bean 容器中移除。
Spring bean factory
负责管理在 spring 容器中被创建的 bean 的生命周期。Bean 的生命周期由两组回调(call back)方法组成。
- 初始化之后调用的回调方法。
- 销毁之前调用的回调方法。
Spring 框架提供了以下四种方式来管理 bean 的生命周期事件:
-
InitializingBean
和DisposableBean
回调接口 - 针对特殊行为的其他
Aware
接口 - Bean 配置文件中的
Custom init()
方法和destroy()
方法 -
@PostConstruct
和@PreDestroy
注解方式
使用 customInit()
和 customDestroy()
方法管理 bean 生命周期的代码样例如下:
<beans>
<bean id="demoBean" class="com.somnus.task.DemoBean" initmethod="customInit" destroy-method="customDestroy"></bean>
</beans>
六、什么是 Spring inner beans?
在 Spring 框架中,无论何时 bean 被使用时,当仅被调用了一个属性。一个明智的做法是将这个 bean 声明为内部 bean。内部 bean 可以用 setter 注入“属性”和构造方法注入“构造参数”的方式来实现。
比如,在我们的应用程序中,一个 Customer 类引用了一个 Person 类,我们的要做的是创建一个 Person 的实例,然后在 Customer 内部使用。
public class Customer{
private Person person;
//Setters and Getters
}
public class Person{
private String name;
private String address;
private int age;
//Setters and Getters
}
内部 bean 的声明方式如下:
<bean id="CustomerBean" class="com.somnus.common.Customer">
<property name="person">
<!-- This is inner bean -->
<bean class="com.howtodoinjava.common.Person">
<property name="name" value="lokesh" />
<property name="address" value="India" />
<property name="age" value="34" />
</bean>
</property>
</bean>
七、请举例说明如何在 Spring 中注入一个 Java Collection?
Spring 提供了以下四种集合类的配置元素:
- : 该标签用来装配可重复的 list 值。
- : 该标签用来装配没有重复的 set 值。
- : 该标签支持注入键和值都是字符串类型的键值对。
下面看一下具体的例子:
<beans>
<!-- Definition for javaCollection -->
<bean id="javaCollection" class="com.howtodoinjava.JavaCollection">
<!-- java.util.List -->
<property name="customList">
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</list>
</property>
<!-- java.util.Set -->
<property name="customSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>UK</value>
</set>
</property>
<!-- java.util.Map -->
<property name="customMap">
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="UK"/>
</map>
</property>
<!-- java.util.Properties -->
<property name="customProperies">
<props>
<prop key="admin">admin@nospam.com</prop>
<prop key="support">support@nospam.com</prop>
</props>
</property>
</bean>
</beans>
八、请解释自动装配模式的区别?
在 Spring 框架*有 5 种自动装配,让我们逐一分析。
-
no
:这是 Spring 框架的默认设置,在该设置下自动装配是关闭的,开发者需要自行在 bean 定义中用标签明确的设置依赖关系。 -
byName
:该选项可以根据 bean 名称设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的名称自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。 -
byType
:该选项可以根据 bean 类型设置依赖关系。当向一个 bean 中自动装配一个属性时,容器将根据 bean 的类型自动在在配置文件中查询一个匹配的 bean。如果找到的话,就装配这个属性,如果没找到的话就报错。 -
constructor
:造器的自动装配和 byType 模式类似,但是仅仅适用于与有构造器相同参数的bean,如果在容器中没有找到与构造器参数类型一致的 bean,那么将会抛出异常。 -
autodetect
:该模式自动探测使用构造器自动装配或者 byType 自动装配。首先,首先会尝试找合适的带参数的构造器,如果找到的话就是用构造器自动装配,如果在 bean 内部没有找到相应的构造器或者是无参构造器,容器就会自动选择 byTpe 的自动装配方式。
九、如何开启基于注解的自动装配?
要使用 @Autowired
,需要注册 AutowiredAnnotationBeanPostProcessor
,可以有以下两种方式来实现:
1、引入配置文件中的下引入 <context:annotation-config>
<beans>
<context:annotation-config />
</beans>
2、在 bean 配置文件中直接引入 AutowiredAnnotationBeanPostProcessor
<beans>
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotati
onBeanPostProcessor"/>
</beans>
十、简述 AOP 和 IOC 概念
AOP:Aspect Oriented Program
, 面向(方面)切面的编程;Filter(过滤器) 也是一种 AOP. AOP 是一种新的方法论, 是对传统 OOP(Object-Oriented Programming
, 面向对象编程) 的补充. AOP 的主要编程对象是切面(aspect), 而切面模块化横切关注点.可以举例通过事务说明.
IOC: Invert Of Control
, 控制反转. 也成为 DI(依赖注入) 其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源.作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为 查找的被动形式.
本文仅供参考!
OC: Invert Of Control
, 控制反转. 也成为 DI(依赖注入) 其思想是反转资源获取的方向. 传统的资源查找方式要求组件向容器发起请求查找资源.作为回应, 容器适时的返回资源. 而应用了 IOC 之后, 则是容器主动地将资源推送给它所管理的组件,组件所要做的仅是选择一种合适的方式来接受资源. 这种行为也被称为 查找的被动形式.
**本文仅供参考!