Spring面试宝典
Spring
1、Spring 框架优点
- **轻量:**Spring是轻量的,基础版本大约2MB
- 控制反转(Inversion of Control): 将对象的创建、依赖管理和生命周期交由Spring容器控制,而非开发者手动管理。实现松耦合
- 面向切面编程(AOP): 支持面向切面编程,把业务逻辑和系统服务(日志记录,权限控制,事务管理)分开
- **事务管理:**Spring提供了一个持续的事务管理接口,可以扩展到上至本地事务下至全局事务(JTA)
- **异常处理:**提供了方便的API把具体技术的异常(比如由JDBC,Hibernate 抛出的)转化为一致的unchecked 异常
2、Spring中的几个基本模块
- Core module
- Bean module
- Context module
- Expression Language module
- JDBC module
- ORM module
- OXM module
- Web module
IOC容器核心流程
1. Bean 定义加载与注册
// 示例:从 XML 配置加载 Bean 定义
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 核心流程(简化):
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {// 1. 创建 BeanFactory(DefaultListableBeanFactory)super();// 2. 设置配置位置setConfigLocations(new String[] {configLocation});// 3. 刷新容器(核心方法)refresh();
}
2. 容器刷新(refresh()
方法)
@Override
public void refresh() throws BeansException, IllegalStateException {synchronized (this.startupShutdownMonitor) {// 1. 准备刷新环境prepareRefresh();// 2. 获取 BeanFactory(DefaultListableBeanFactory)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();// 3. 配置 BeanFactoryprepareBeanFactory(beanFactory);try {// 4. 允许子类自定义 BeanFactorypostProcessBeanFactory(beanFactory);// 5. 调用 BeanFactoryPostProcessor(如 @Configuration 处理)invokeBeanFactoryPostProcessors(beanFactory);// 6. 注册 BeanPostProcessor(如 AOP 代理创建器)registerBeanPostProcessors(beanFactory);// 7. 初始化消息源(国际化)initMessageSource();// 8. 初始化事件广播器initApplicationEventMulticaster();// 9. 子类初始化特殊 BeanonRefresh();// 10. 注册监听器registerListeners();// 11. 实例化所有非懒加载的单例 BeanfinishBeanFactoryInitialization(beanFactory);// 12. 完成刷新,发布事件finishRefresh();}catch (BeansException ex) {// 异常处理destroyBeans();cancelRefresh(ex);throw ex;}}
}
3. Bean 实例化与依赖注入
// 创建 Bean 的核心方法(AbstractAutowireCapableBeanFactory)
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {// 1. 创建 Bean 实例(通过构造器或工厂方法)BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);// 2. 处理 BeanDefinition 中的属性值(尚未注入)applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);// 3. 处理循环依赖(提前暴露半成品 Bean)boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));}// 4. 填充属性(依赖注入)populateBean(beanName, mbd, instanceWrapper);// 5. 初始化 Bean(调用初始化方法、应用 BeanPostProcessor)exposedObject = initializeBean(beanName, exposedObject, mbd);// 6. 处理循环依赖(检查代理)if (earlySingletonExposure) {Object earlySingletonReference = getSingleton(beanName, false);// ...}return exposedObject;
}
3、BeanFactory与ApplicationContext
在 Spring 框架中,BeanFactory 和 ApplicationContext 是IOC容器的两个大核心接口。其中ApplicationContext 是BeanFactory的子接口。
- BeanFactory: 基础容器接口(IOC的底层实现),包含了各种Bean的定义,读取bean配置文档,管理Bean的加载、实例化,控制Bean的生命周期,维护Bean之间的依赖关系。BeanFactory 简单粗暴,可以理解为就是HashMap,key是BeanName,Value是Bean实例。通常只提供注册和获取两个功能,我们可以称之为“低级容器”。
- ApplicationContext:可称为“高级容器”,扩展了 BeanFactory,因此具备了更多的功能。提供事件发布、国际化等功能,这个接口定义了一个refresh 方法,用于刷新整个容器,即重新加载/刷新所有的的bean。ApplicationContext是所有实际应用场景的首选
功能对比
特性 | BeanFactory | ApplicationContext |
---|---|---|
Bean 加载方式 | 懒加载(按需初始化) | 预加载(启动时初始化所有单例 Bean) |
AOP 支持 | 需手动集成 | 原生集成(通过 @AspectJ 或 XML) |
事件机制 | 不支持 | 支持 ApplicationEvent 发布/监听 |
国际化 (i18n) | 不支持 | 支持 MessageSource 资源束 |
资源访问 | 基础支持 | 扩展 ResourceLoader (支持类路径/URL/文件系统) |
环境配置 | 无 | 集成 Environment (Profile + PropertySource) |
与 Spring Boot 整合 | 不直接使用 | 默认容器(SpringApplication.run() 创建) |
性能 | 启动快(延迟加载) | 启动稍慢(预加载),运行时性能更优 |
核心API解析
1. BeanFactory 核心方法
public interface BeanFactory {Object getBean(String name) throws BeansException;<T> T getBean(Class<T> requiredType) throws BeansException;boolean containsBean(String name);Class<?> getType(String name) throws NoSuchBeanDefinitionException;boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
}
2. ApplicationContext 扩展能力
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory {// 事件发布void publishEvent(ApplicationEvent event);// 国际化String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;// 资源访问Resource getResource(String location);// 环境配置Environment getEnvironment();
}
使用场景对比
场景 1:基础依赖注入
// 使用 BeanFactory
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
UserService service = factory.getBean(UserService.class);// 使用 ApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
UserService service = ctx.getBean(UserService.class);
场景 2:事件驱动编程(仅 ApplicationContext 支持)
// 自定义事件
public class OrderEvent extends ApplicationEvent { ... }// 事件监听
@Component
public class NotificationListener implements ApplicationListener<OrderEvent> {@Overridepublic void onApplicationEvent(OrderEvent event) {// 发送通知}
}// 事件发布
ctx.publishEvent(new OrderEvent(order));