Spring高频拓展
一、Spring 三种配置方式对比(XML / 注解 / JavaConfig)
1、三种配置方式介绍
-
XML配置:早期Spring方式,将Bean全部写在xml文件中,解耦强、修改无需改代码。
-
注解配置:@Component、@Service、@Repository,自动扫描Bean,简单快捷。
-
JavaConfig配置:@Configuration + @Bean,纯Java代码配置,无XML,类型安全、编译检查。
2、优缺点对比 🔴
| 配置方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| XML | 彻底解耦、修改不用改代码 | 繁琐、可读性差、无编译检查 | 老旧项目、第三方复杂Bean |
| 注解 | 简洁、开发快、自动扫描 | 耦合代码、无法外部修改 | 业务层普通Bean(Service、Dao) |
| JavaConfig | 类型安全、编译校验、优雅、无XML | 少量代码量 | 第三方组件、自定义Bean、中间件配置 |
3、@Configuration 🟠
-
Full模式(默认):添加@Configuration,内部@Bean方法被拦截、单例、不会重复创建。
-
Lite模式:不加@Configuration,只加@Component,内部@Bean每次调用都会new新对象。
Spring为@Configuration类生成CGLIB代理,拦截@Bean方法,保证容器中Bean唯一单例。
二、SpringBoot 自动配置原理(SPI + @EnableAutoConfiguration)
1、核心 🔴
加载SPI配置 → 读取自动配置类 → 条件注解按需注入Bean → 完成自动装配
2、详细流程
-
@EnableAutoConfiguration:开启自动配置,底层导入 AutoConfigurationImportSelector。
-
SPI机制:读取
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件。 -
加载所有自动配置类(如WebMvcAutoConfiguration、DataSourceAutoConfiguration)。
-
条件注解生效:@ConditionalOnClass、@ConditionalOnMissingBean,判断类是否存在、Bean是否存在。
-
满足条件则自动创建Bean,注入Spring容器。
3、SPI机制作用
SPI:服务提供者接口,解耦配置与代码,SpringBoot利用SPI实现“第三方组件自动加载”,不用手动写Bean。
三、配置注入三大注解:@Value / @PropertySource / @ConfigurationProperties
1、三者区别 🟠
| 注解 | 作用 | 适用场景 | 优点 |
|---|---|---|---|
| @Value | 单个简单值注入 | 零散配置、少量字段 | 简单、灵活 |
| @PropertySource | 加载外部properties配置文件 | 自定义配置文件 | 分离配置、不写死代码 |
| @ConfigurationProperties | 批量绑定配置、前缀绑定 | 一组关联配置(数据库、线程池) | 批量注入、类型安全、校验、优雅 |
2、写法示例(默写)
|
|
3、面试总结
-
少量零散配置 → @Value
-
自定义配置文件 → @PropertySource
-
一组同类配置 → @ConfigurationProperties(推荐)
四、Spring 事件驱动模型(ApplicationEvent)
1、核心作用
解耦:发布事件、监听事件,实现业务解耦(观察者模式)。
2、三大核心组件
-
ApplicationEvent:自定义事件(继承)。
-
ApplicationListener:事件监听者,监听事件并处理。
-
ApplicationEventPublisher:事件发布器,发布事件。
3、简单流程
业务代码 → 发布事件 → 监听者捕获 → 异步/同步处理业务
4、使用场景
-
用户注册成功发送短信、邮件
-
订单创建、订单完成、业务解耦
-
Spring内置事件:容器刷新、容器关闭
五、@Profile 多环境配置
1、作用
区分开发、测试、生产环境,不同环境加载不同Bean、不同配置。
2、使用方式
|
|
3、激活环境
-
配置文件:spring.profiles.active=dev
-
启动参数:–spring.profiles.active=prod
六、高频易错点汇总 🟠
1、@Autowired 和 @Resource 区别 🔴
| 对比 | @Autowired | @Resource |
|---|---|---|
| 来源 | Spring注解 | JSR250 Java原生规范 |
| 默认规则 | 按类型byType | 默认按名称byName |
| 依赖required | 默认必须注入,不可为空 | 可以为空 |
| 适用 | Spring项目主流 | 通用性高、脱离Spring也能用 |
Autowired默认按类型注入,Resource默认按名称注入。
2、Bean 名称生成规则(极易错)
-
注解无指定name:首字母小写、类名作为Bean名称(UserService → userService)。
-
注解指定name:以指定名字为准。
-
@Bean 默认名称:方法名作为Bean名称。
-
特殊规则:类前两位都大写,则Bean名称不变(ABCService→ABCService)。
3、事务传播行为易错场景(大坑) 🔴
易错1:REQUIRED(默认)
父子同一事务,只要一个异常,全部回滚。
易错2:REQUIRES_NEW
新开独立事务,互不影响,外层回滚内层不回滚(日志必用)。
易错3:NESTED
嵌套事务,保存点机制,父回滚子必回滚,子回滚父可继续。
易错4:内部调用事务一定失效
this.方法()不走代理,事务彻底失效。
易错5:异常捕获不抛出,事务不回滚
Spring默认只回滚RuntimeException,捕获不抛异常不会回滚。
易错6:非public方法事务失效
AOP动态代理无法拦截private/protected方法。