Java面试题详解
一、谈谈你对IOC与DI的理解
问题:在面试过程中,面试官提起Spring时,一定会问到IOC和DI的相关问题。但往往我们对IOC和DI的理解都是一知半解。那么,什么是IOC呢?
答案:
- IOC(控制反转):是一种设计理念,要求将对象的创建和控制交给第三方容器,而不是在代码中直接使用
new
关键字创建对象。它通过将对象的创建和管理交给容器来实现解耦,使得代码更加灵活和可维护。 - DI(依赖注入):是IOC的具体实现方式,指在运行时由容器动态地将依赖对象注入到需要它们的组件中。通过DI,组件不需要自己创建依赖对象,只需要声明需要的依赖,由容器负责提供,进一步实现了组件间的解耦。
示例:
// 传统方式创建对象
IDao dao = new UserDao();// 使用Spring的IOC和DI
IDao dao = applicationContext.getBean("userDao", IDao.class);
解释:
- 在传统方式中,如果需要更换
UserDao
为其他实现类,需要修改所有使用UserDao
的地方,维护成本高。 - 使用Spring的IOC和DI后,对象的创建和管理交给
ApplicationContext
容器,通过配置文件或注解定义对象的依赖关系。当需要更换实现类时,只需修改配置文件,无需修改业务代码,大大提高了系统的可维护性和扩展性。
二、谈谈你对Spring框架中BeanFactory与ApplicationContext的区别
问题:在Spring框架中,BeanFactory和ApplicationContext有什么区别?
答案:
- BeanFactory:是IOC容器最顶级的接口,提供基本的IOC容器功能,如Bean的创建和管理。它的实现类只实现了IOC容器对象管理的基本功能,使用对象延迟加载,只有在首次调用
getBean
时才初始化Bean。 - ApplicationContext:在BeanFactory基础上扩展了一系列功能,如国际化、自动装配、事件发布等。它在容器初始化时就预加载所有单例Bean,提高访问效率,是日常开发中常用的IOC容器。
表格对比:
特性 | BeanFactory | ApplicationContext |
---|---|---|
功能范围 | 提供基本的IOC容器功能 | 在BeanFactory基础上扩展了更多企业级功能 |
加载方式 | 按需加载,只有在首次调用getBean时才初始化Bean | 容器初始化时就预加载所有单例Bean |
配置方式 | 支持XML、注解等多种配置方式 | 支持XML、注解等多种配置方式 |
使用场景 | 适用于轻量级应用或需要延迟加载的场景 | 是Spring框架中推荐使用的IOC容器,适用于大多数应用场景 |
三、请你介绍一下Spring中使用了哪些设计模式
问题:在Spring中使用了哪些设计模式?
答案:
- 工厂模式:IOC容器作为对象工厂,根据配置信息动态创建对象,如
BeanFactory
和ApplicationContext
。 - 单例模式:Spring容器默认以单例模式管理Bean,确保每个Bean在容器中只有一个实例。
- 代理模式:AOP功能的底层实现,通过代理对象为原始对象增加额外功能,如JDK动态代理和CGLIB代理。
- 适配器模式:AOP中的通知机制使用适配器模式将不同类型的通知适配到统一的拦截器链中。
- 观察者模式:Spring事件驱动模型中,应用上下文发布事件,监听器监听并响应事件。
- 模板方法模式:在数据访问层(DAO)中,
JdbcTemplate
等模板类封装了JDBC操作的通用流程,简化了数据访问代码。
示例:
- 工厂模式:通过
ApplicationContext
获取Bean实例,无需关心创建细节。 - 单例模式:配置文件中设置
<bean>
标签的singleton
属性为true
(默认值),即可让该Bean以单例模式存在。 - 代理模式:使用
@Aspect
定义切面,通过代理为业务方法添加横切关注点,如日志记录、事务管理等。 - 适配器模式:AOP中的
MethodBeforeAdvice
、AfterReturningAdvice
、ThrowsAdvice
等适配器将不同类型的通知转换为统一的拦截器接口。 - 观察者模式:通过
ApplicationEventPublisher
发布事件,ApplicationListener
监听并处理事件,实现对象间的一对多依赖关系。 - 模板方法模式:使用
JdbcTemplate
的queryForObject
、queryForList
等模板方法,简化数据查询操作,无需关注底层JDBC细节。