注解开发时核心 必须熟悉使用并了解原理 !!!
一、IOC/DI 核心思想(一句话理解)
传统开发: 程序员手动 new 对象,对象间强耦合
Spring 开发: 容器自动创建和管理对象,对象间松耦合
核心价值
-
解耦:修改实现类只需改配置,不改代码
-
可测试:便于单元测试(可注入 Mock 对象)
-
可维护:依赖关系清晰,易于维护
二、IOC 容器核心原理(面试重点)
2.1 容器层级结构
text
BeanFactory (基础功能)
└── ApplicationContext (企业级功能,推荐使用)
├── ClassPathXmlApplicationContext
├── FileSystemXmlApplicationContext
└── AnnotationConfigApplicationContext
2.2 BeanFactory vs ApplicationContext(必背)
| 特性 | BeanFactory | ApplicationContext |
|---|---|---|
| 加载时机 | 懒加载(用时创建) | 立即加载(启动时创建) |
| 功能范围 | 基础Bean管理 | 企业级功能(事件、资源等) |
| 适用场景 | 资源受限环境 | 生产环境(推荐) |
2.3 Bean 生命周期(核心流程)
text
实例化 → 属性注入 → 初始化 → 使用 → 销毁
关键点:
-
单例Bean:容器启动时创建,关闭时销毁
-
多例Bean:每次getBean时创建,容器不管理销毁
2.4 循环依赖解决方案(高频面试题)
三级缓存机制:
-
一级缓存:完整Bean
-
二级缓存:半成品Bean(已实例化,未注入)
-
三级缓存:Bean工厂
解决条件:
-
✅ 单例Bean + Setter注入
-
❌ 多例Bean + 构造器注入
三、注解开发深度解析(实战重点)
3.1 核心注解速查
| 注解 | 作用 | 等价XML |
|---|---|---|
@Component | 通用组件 | <bean> |
@Service | 业务层 | <bean> |
@Repository | 数据层 | <bean> |
@Controller | 控制层 | <bean> |
@Autowired | 自动装配 | <property> |
@Value | 注入值 | <value> |
3.2 @Autowired 自动装配流程
-
按类型匹配 → 找到唯一Bean直接注入
-
找到多个 → 按属性名匹配
-
仍不唯一 → 使用@Qualifier指定
-
找不到 → 根据required决定是否报错
实战代码:
java
@Service
public class UserService {
// 1. 按类型注入
@Autowired
private UserDao userDao;
// 2. 按名称注入
@Autowired
private UserDao userDaoImpl;
// 3. 明确指定
@Autowired
@Qualifier("userDaoMysql")
private UserDao userDao;
}
3.3 条件装配(进阶功能)
java
@Configuration
public class DataSourceConfig {
@Bean
@ConditionalOnProperty(name = "db.type", havingValue = "mysql")
public DataSource mysqlDataSource() {
return new MysqlDataSource();
}
@Bean
@ConditionalOnProperty(name = "db.type", havingValue = "oracle")
public DataSource oracleDataSource() {
return new OracleDataSource();
}
}
四、第三方Bean管理(实战必备)
4.1 @Bean 注解使用
java
@Configuration
public class JdbcConfig {
@Value("${jdbc.url}")
private String url;
@Value("${jdbc.username}")
private String username;
// 管理Druid数据源
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setUrl(url);
ds.setUsername(username);
return ds;
}
// 带依赖注入的Bean
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
4.2 配置文件读取
java
@Configuration
@PropertySource("classpath:jdbc.properties") // 加载配置文件
@ComponentScan("com.example.service") // 扫描组件
public class AppConfig {
@Value("${app.name}")
private String appName;
}
五、Spring整合实战(企业开发必备)
5.1 整合MyBatis(最常用)
核心配置:
java
@Configuration
public class MyBatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setTypeAliasesPackage("com.example.entity");
return factory;
}
@Bean
public MapperScannerConfigurer mapperScanner() {
MapperScannerConfigurer scanner = new MapperScannerConfigurer();
scanner.setBasePackage("com.example.dao");
return scanner;
}
}
事务管理:
java
@Configuration
@EnableTransactionManagement // 开启事务注解
public class TransactionConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
// 使用事务
@Service
public class UserService {
@Transactional // 声明事务
public void updateUser(User user) {
userDao.update(user);
}
}
5.2 整合Junit测试
java
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = AppConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
@Transactional
@Rollback // 测试后回滚
public void testUpdateUser() {
User user = new User();
userService.updateUser(user);
// 断言验证
}
}
六、高频面试题精讲
6.1 Spring 如何解决循环依赖?
回答要点:
-
使用三级缓存解决单例Bean的Setter注入循环依赖
-
无法解决构造器注入和多例Bean的循环依赖
-
核心思想:提前暴露半成品Bean
标准答案:
"Spring通过三级缓存机制解决循环依赖问题。具体来说:一级缓存存放完整Bean,二级缓存存放半成品Bean,三级缓存存放Bean工厂。当Bean A依赖Bean B,而Bean B又依赖Bean A时,Spring会在创建A的半成品实例后,将其放入二级缓存,然后继续创建B。当B需要注入A时,就能从二级缓存拿到A的半成品实例,从而打破循环依赖。"
6.2 @Autowired 和 @Resource 的区别?
| 特性 | @Autowired | @Resource |
|---|---|---|
| 来源 | Spring框架 | Java标准 |
| 默认注入 | 按类型 | 按名称 |
| required | 支持 | 不支持 |
| 构造器注入 | 支持 | 不支持 |
选择建议: 纯Spring项目用@Autowired,需要跨框架兼容用@Resource
6.3 BeanFactory 和 ApplicationContext 如何选择?
ApplicationContext 优势:
-
功能全面(事件、国际化、资源加载)
-
启动时检查配置错误
-
企业级开发推荐使用
BeanFactory 适用场景:
-
资源极度受限的嵌入式设备
-
需要极致启动速度的特殊场景
6.4 单例Bean的线程安全问题?
核心观点:
-
无状态Bean(无成员变量)天然线程安全
-
有状态Bean需要额外处理
解决方案:
java
@Service
public class StatelessService { // 无状态,线程安全
public void process(String data) {
// 只使用局部变量和参数
}
}
@Service
@Scope("prototype") // 有状态,使用多例
public class StatefulService {
private int count;
public synchronized void increment() { // 或使用锁
count++;
}
}
6.5 Spring 管理事务的原理?
回答要点:
-
基于AOP实现
-
使用@Transactional注解
-
默认对RuntimeException回滚
实战配置:
java
@Transactional(
propagation = Propagation.REQUIRED, // 事务传播行为
isolation = Isolation.DEFAULT, // 隔离级别
timeout = 30, // 超时时间
rollbackFor = Exception.class // 回滚异常
)
public void businessMethod() {
// 业务操作
}
七、实战避坑指南
7.1 常见配置错误
-
❌
@Value("${undefined.property}")- 属性不存在 -
❌ 循环依赖使用构造器注入 - 无法解决
-
❌ 多例Bean中使用@PreDestroy - 不会执行
7.2 性能优化建议
-
无状态Bean使用单例(默认)
-
及时释放多例Bean资源
-
合理使用懒加载@Lazy
7.3 最佳实践
-
面向接口编程:便于切换实现
-
使用构造器注入:强制依赖明确
-
合理划分包结构:便于组件扫描
-
配置文件外部化:不同环境不同配置
总结
核心掌握:
-
IOC/DI 解耦思想
-
注解开发流程
-
第三方Bean管理
-
整合MyBatis和事务
面试突出:
-
循环依赖解决方案
-
自动装配原理
-
事务管理机制
实战重点:
-
配置文件管理
-
组件扫描配置
-
测试框架整合
记住:Spring的核心价值在于解耦,所有特性都围绕这个目标设计。掌握原理,灵活运用,才能在实际开发中游刃有余。
1963

被折叠的 条评论
为什么被折叠?



