牛客面经——Spring篇
1. 说说Spring Boot常用注解
2. 说说Spring Boot的启动流程
- 入口触发:通过@SpringBootApplication主类的main方法调用SpringApplication.run()
- 环境准备:加载配置
- 上下文创建:实例化ApplicantionContext
- 自动配置:通过@EnableAutoConfiguration触发,注册必要Bean
- 刷新上下文:初始化所有单例 Bean
- 应用就绪:发布ApplicationReadyEvent
3. 说说你对IoC的理解
Ioc是控制反转,指将对象创建和依赖管理的控制权从程序转移至外部容器。
实现方式为DI(依赖注入): 分为构造器注入(推荐)
@Service
public class UserService {
private final UserRepository userRepository;
@Autowired // 构造器注入(@Autowired可省略)
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
Setter方法注入
4. 说说你对AOP的理解
AOP是面向切面编程,通过横向抽取共性功能,解决代码重复和耦合问题。其基于动态代理(基于接口的JDK动态代理或基于类的CGLib动态代理)实现。
核心概念:
- @Aspect切面:封装横切逻辑的模块
- @Pointcut切入点
- Advice通知:分为@Before,@After,@Around
@Aspect
@Component
public class LoggingAspect {
// 定义切入点
@Pointcut("execution(* com.example.service.UserService.*(..))")
private void userServiceMethods() {}
// 使用切入点的前置通知
@Before("userServiceMethods()")
public void beforeUserServiceMethod(JoinPoint joinPoint) {
System.out.println("Before method: " + joinPoint.getSignature().getName());
}
}
使用场景有日志记录,权限控制,公共字段填充等方面。
5. 说说Bean的生命周期
- 实例化:通过反射创建 Bean 的原始对象
- 属性注入:填充 Bean 的依赖属性(如通过@Autowired、@Resource或 XML 配置的property)
- 初始化:@PostConstruct 注解方法,初始化阶段是开发者自定义逻辑的核心扩展点
- 使用
- 销毁:容器关闭时释放 单例Bean
6. 说说@Autowired和@Resource注解的区别
@Autowired是SpringBoot注解,只能按类型注入,需要加@Qualifier注解才能指定名称,可设置允许依赖为null
@Resource是JDK注解,默认按名称注入,匹配失败时再按类型注入。更通用。
7. 说说Spring事务管理
- 编程式事务:通过手动编写代码显示控制事务的开启,提交,回滚,等细节。灵活性高但侵入性强。
- 声明式事务:通过AOP自动管理事务,是Spring推荐的主流方式。通过@Transactional注解或xml配置
8. 介绍一下Spring MVC的执行流程。
- 用户发起请求
- 前端控制器接受请求
- 处理器映射:根据请求 URL 查找对应的处理器
- 处理器适配
- 参数解析与数据绑定
- 调用Controller方法
- 返回结果
- 视图解析,视图渲染
9. 讲一下 Spring 中用到的设计模式?
- 工厂模式:
- 单例模式:全局单例Bean
- 原型模式:
- 代理模式:通过代理对象控制对目标对象的访问。
- 观察者模式:定义对象间的一对多依赖关系,状态变化自动通知观察者。
- 责任链模式
10. 循环依赖是什么,怎么解决使用三级缓存?
循环依赖是两个或多个Bean之间相互注入形成依赖,场景有三种:
只有构造器注入这一种可以解决:
- 三级缓存Bean工厂对象,二级缓存已实例化但未完成属性注入的Bean,一级缓存完全初始化后的单例Bean