Spring 笔记:几个把我卡住的点

举报
yd_241780069 发表于 2026/10/21 20:06:11 2026/10/21
【摘要】 IOC控制反转这词第一次看确实懵。后来我自己的理解就是:以前对象自己 new、自己 set 依赖,现在这活交给容器干了。@Autowired 注不进来,我遇到过两次。一次是启动类在 com.example.demo,我的类在 com.other 下面,压根没扫到。另一次是同一个接口俩实现类,Spring 不知道给哪个,直接报 NoUniqueBeanDefinitionException。...

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 管增强。别的都是在这上面长出来的。先写到这,后面遇到新问题再补。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。