SpringBoot注解的作用

  1. @SpringBootApplication: 来源于spring-boot-starter,springboot的核心注解。
    SpringBoot标注在某一个类上,说明该类是SpringBoot的主配置类,运行这个类的main方式启动SpringBoot应用。

  2. @SpringBootConfiguration: 声明是springboot的配置类
    @Configuration: 声明是配置类
    注意:这两个注解,一个用于springboot中,一个用于spring中

  3. **@ComponentScan:**开启注解扫描

  4. @Target(ElementType.TYPE)、@Retention(RetentionPolicy.RUNTIME)、@Documented:这三个是元注解,修饰注解。

  5. @EnableAutoConfiguration: 开启自动装配的核心注解
    点进去,有一个核心的功能:@Import(AutoConfigurationImportSelector.class):自动导入选择器、筛查器。

  6. @Import(AutoConfigurationImportSelector.class) :自动配置选择器、筛查器(增强版)
    点击AutoConfigurationImportSelector.class进入,找到getAutoConfigurationEntry()方法(核心方法),点击该方法,跳转到该方法所在位置。
    下面是getAutoConfigurationEntry()方法自动配置的核心代码:

    java 复制代码
    /**
     * 获取自动配置条目 - Spring Boot自动配置的核心方法
     * @param annotationMetadata @EnableAutoConfiguration注解的元数据
     * @return 自动配置条目,包含需要导入的配置类列表
     */
    protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
        
        // 1. 检查自动配置是否启用
        // 如果@EnableAutoConfiguration的enabled属性为false,返回空条目
        if (!isEnabled(annotationMetadata)) {
            return EMPTY_ENTRY;  // 返回空配置,不进行任何自动配置
        }
        
        // 2. 获取@EnableAutoConfiguration注解的属性
        // 例如:exclude, excludeName等属性
        AnnotationAttributes attributes = getAttributes(annotationMetadata);
        
        // 3. 获取所有候选的自动配置类
        // 从META-INF/spring.factories文件中读取key为
        // org.springframework.boot.autoconfigure.EnableAutoConfiguration的所有配置类
        List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
        
        // 4. 移除重复的配置类(可能在不同jar包中重复定义)
        configurations = removeDuplicates(configurations);
        
        // 5. 获取需要排除的配置类
        // 从@EnableAutoConfiguration的exclude和excludeName属性获取
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        
        // 6. 检查排除的类是否有效
        // 确保要排除的类确实在候选配置列表中
        checkExcludedClasses(configurations, exclusions);
        
        // 7. 从候选配置中移除被排除的配置类
        configurations.removeAll(exclusions);
        
        // 8. 使用自动配置过滤器进行过滤
        // Spring Boot 2.7+新增的机制,通过@AutoConfiguration注解的before/beforeName等属性排序和过滤
        configurations = getConfigurationClassFilter().filter(configurations);
        
        // 9. 触发自动配置导入事件
        // 允许监听器在自动配置类被导入前进行干预
        fireAutoConfigurationImportEvents(configurations, exclusions);
        
        // 10. 返回最终的自动配置条目
        // 包含经过所有处理后的配置类列表和排除的类
        return new AutoConfigurationEntry(configurations, exclusions);
    }
  7. **@AutoConfigurationPackage:**自动配置包

  8. @Import(AutoConfigurationPackages.Registrar.class): 自动配置,注册基础包路径
    在**@AutoConfigurationPackage** 注解中
    核心逻辑:

    java 复制代码
    // AutoConfigurationPackages.Registrar 的核心逻辑
    static class Registrar implements ImportBeanDefinitionRegistrar {
        @Override
        public void registerBeanDefinitions(
                AnnotationMetadata metadata, 
                BeanDefinitionRegistry registry) {
            
            // 1. 获取被@AutoConfigurationPackage注解的类所在的包
            // 通常是主启动类所在的包
            PackageImport packageImport = new PackageImport(metadata);
            
            // 2. 将这个包路径注册到Spring容器中
            register(registry, packageImport.getPackageName());
        }
    }
  9. **@Import(EnableAutoConfigurationImportSelector.class):**自动配置选择器(SpringBot 1.x版本),基本自动配置加载。

执行流程时间线:

java 复制代码
应用启动
    ↓
@SpringBootApplication生效
    ↓
├─ @ComponentScan执行
│   ↓
│   扫描当前包及子包下的@Component、@Service等
│
└─ @EnableAutoConfiguration执行
    ↓
    ├─ @AutoConfigurationPackage
    │   ↓
    │   AutoConfigurationPackages.Registrar.registerBeanDefinitions()
    │   ↓
    │   注册主类包路径到BasePackages
    │
    └─ @Import(AutoConfigurationImportSelector.class)
        ↓
        AutoConfigurationImportSelector.selectImports()
        ↓
        加载并过滤所有自动配置类
        ↓
        导入符合条件的配置类到Spring容器

项目结构:

java 复制代码
com.example.myapp
├── Application.java          # @SpringBootApplication
├── controller
│   └── UserController.java   # 会被@ComponentScan扫描到
├── service
│   └── UserService.java      # 会被@ComponentScan扫描到
└── entity
    └── User.java            # JPA实体,需要基础包信息
相关推荐
Libby博仙2 小时前
Spring Boot 条件化注解深度解析
java·spring boot·后端
我是小疯子662 小时前
深入解析C++右值引用与移动语义
java·开发语言·算法
better_liang2 小时前
每日Java面试场景题知识点之-JUC锁的底层原理
java·并发编程·juc·锁机制·reentrantlock·readwritelock·底层原理
悟能不能悟2 小时前
Elastic Stack 中两种主要查询语言 KQL (Kibana Query Language) 和 Lucene 的详细对比和解释。
java·开发语言
我是一只小青蛙8882 小时前
Java连接MySQL数据库实战指南
java
夏末4722 小时前
Java异常处理终极指南:从入门到企业级实战,让程序稳如老狗!
java·java ee
子非鱼9212 小时前
SpringBoot快速上手
java·spring boot·后端
techzhi2 小时前
Apifox CLI + GitLab CI:接口自动化测试实施记录
java·ci/cd·kubernetes·gitlab·yapi·运维开发·fastapi
我爱娃哈哈2 小时前
SpringBoot + XXL-JOB + Quartz:任务调度双引擎选型与高可用调度平台搭建
java·spring boot·后端