@SpringBootApplication之scanBasePackages
@SpringBootApplication(scanBasePackages = {"${yudao.info.base-package}.server", "${yudao.info.base-package}.module"})
这句话什么意思?
让我解释一下这个注解的含义:
@SpringBootApplication(scanBasePackages = {...}) 是 Spring Boot 的核心注解,它有以下几个要点:
-
@SpringBootApplication是一个复合注解,相当于同时使用了:@Configuration(标明这是一个配置类)@EnableAutoConfiguration(启用 Spring Boot 的自动配置机制)@ComponentScan(组件扫描)
-
scanBasePackages参数指定了 Spring 需要扫描的包路径:${yudao.info.base-package}.server- 扫描 server 包${yudao.info.base-package}.module- 扫描 module 包${yudao.info.base-package}是一个配置属性,可能在配置文件(如 application.properties 或 application.yml)中定义
-
这里使用了 Spring 的属性占位符
${}语法,表示这些值会在运行时从配置文件中读取。比如如果yudao.info.base-package=cn.iocoder.yudao,那么实际扫描的包路径就是:cn.iocoder.yudao.servercn.iocoder.yudao.module
-
Spring 会在这些包及其子包下搜索带有 Spring 注解的类(如
@Component、@Service、@Controller等),并将它们注册为 Spring Bean。
这种配置方式的好处是:
- 可以通过配置文件灵活修改要扫描的包路径
- 明确限定了组件扫描范围,避免扫描不必要的包
- 有助于模块化管理,清晰地分离 server 和 module 相关的组件
那么通过scanBasePackages 扫描后,是把bean加载到内存吗?
是的,你理解得对。让我详细解释这个过程:
-
组件扫描阶段:
- Spring 通过
scanBasePackages指定的路径扫描所有类 - 寻找带有特定注解的类,如:
@Component@Service@Controller@Repository@Configuration等
- Spring 通过
-
Bean 定义注册阶段:
- 将找到的类解析为 BeanDefinition(Bean 的定义信息)
- 将 BeanDefinition 注册到 BeanFactory(Bean 工厂)中
-
Bean 实例化阶段:
- Spring 容器启动时,会根据 BeanDefinition 创建 Bean 实例
- 按照 Bean 的作用域(Scope)来管理实例:
singleton(默认):创建单个实例存储在内存中prototype:每次请求都创建新实例- 其他作用域(request、session 等)
-
Bean 初始化阶段:
- 注入依赖(通过
@Autowired等) - 执行初始化方法
- 应用 AOP 代理(如果需要)
- 注入依赖(通过
-
存储在内存中:
- 单例(singleton)Bean 被保存在 Spring 容器的单例池中(ConcurrentHashMap)
- 可以随时通过 Spring 上下文获取
- 在应用运行期间一直存在于内存中
示意图:
扫描 -> 注册 -> 实例化 -> 初始化 -> 存储在内存
[类文件] -> [BeanDefinition] -> [Bean实例] -> [完整Bean] -> [单例池]
这就是为什么 Spring Boot 应用启动时会占用一定内存,因为它需要预先创建和存储这些 Bean。这种机制的好处是:
- 提供了单例管理
- 实现了依赖注入
- 提高了性能(不需要重复创建)
- 便于统一管理生命周期
浙公网安备 33010602011771号