Spring 笔记:几个把我卡住的点
IOC
控制反转这词第一次看确实懵。后来我自己的理解就是:以前对象自己 new、自己 set 依赖,现在这活交给容器干了。
@Autowired 注不进来,我遇到过两次。一次是启动类在 com.example.demo,我的类在 com.other 下面,压根没扫到。另一次是同一个接口俩实现类,Spring 不知道给哪个,直接报 NoUniqueBeanDefinitionException。后来用 @Primary 标了一个默认的才过去。
Bean 生命周期
背是背不下来的,我是照着几个节点串的:实例化 → 属性填充 → 初始化前 → 初始化 → 初始化后 → 使用 → 销毁。
有个细节得记一下:@Autowired 是在属性填充那一步完成的,所以构造函数里拿不到注入的字段,是 null。想用就得构造器注入,把依赖放参数里。
@Service
public class OrderService {
private final UserService userService;
public OrderService(UserService userService) {
this.userService = userService;
}
}
顺便说一句,构造器注入现在是官方推荐的,不可变、好测试,还能早点暴露循环依赖。
AOP
同类内部调用不走代理,这个坑我踩过不止一次。
@Service
public class UserService {
public void methodA() {
methodB(); // 走的是 this,不是代理对象
}
@Transactional
public void methodB() { }
}
methodB 上的事务不会生效。原因是 methodA 里直接调 methodB,用的是原始对象,切面根本没参与进来。要么注入自己,要么把 methodB 挪到另一个 Bean 里。我一般选后者,虽然多一个类,但至少不别扭。
@Transactional 失效还有几种:方法不是 public、异常被 catch 了没抛出去、引擎不支持事务(比如 MyISAM)、对象是自己 new 的不是 Spring 管的。这几个排查的时候挨个过一遍基本就能定位。
@Configuration 和 @Component
都能注册 Bean,区别在 @Bean 方法的调用上。
@Configuration 的类被 CGLIB 增强过,里面 userDao() 调几次都返回同一个实例;@Component 里就不是了,每次调用都是 new 一个。要保证单例就得用 @Configuration。
自动配置
@SpringBootApplication 里关键是 @EnableAutoConfiguration。2.x 从 spring.factories 读配置类,3.x 换成 AutoConfiguration.imports 了。读进来之后靠条件注解决定加不加载,常用的是 @ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty。@ConditionalOnMissingBean 是"默认配置能被覆盖"的关键,看懂这个,大部分 starter 的源码就不难读了。
小结
Spring 核心就两块:IOC 管对象,AOP 管增强。别的都是在这上面长出来的。先写到这,后面遇到新问题再补。
- 点赞
- 收藏
- 关注作者
评论(0)