@AutoConfiguration注解详解

@AutoConfiguration属于springboot当中autoconfigure包下的注解。springboot给我们提供了好多AutoConfiguration,例如关于缓存cache的有CacheAutoConfiguration,关于定时任务quartz的有QuartzAutoConfiguration,这些AutoConfiguration你会发现基本上都会拿@AutoConfiguration来修饰。本篇来彻底了解@AutoConfiguration到底有什么作用,以及到底如何应用他。

一、观察@AutoConfiguration源码

源码当中有三个元注解:

  • @Target({ElementType.TYPE}): 使用范围接口、类、枚举、注解
  • @Retention(RetentionPolicy.RUNTIME): @Retention是用来修饰注解的生命周期的,RetentionPolicy.RUNTIME代表的是不仅被保存到class文件中,jvm加载class文件之后,仍然存在;一直有效!
  • @Documented: @Documented和@Deprecated注解长得有点像,@Deprecated是用来标注某个类或者方法不建议再继续使用,@Documented只能用在注解上,如果一个注解@B,被@Documented标注,那么被@B修饰的类,生成Javadoc文档时,会显示@B。

除了元注解外还有三个注解:

  • @Configuration: 这个是开发当中最常用的注解,他属于是@Component注解的扩展注解,同@Controller、@Service等几个注解的功能是一样的,只要在类上添加了该注解,然后在springboot的扫描范围内,启动项目的时候会将该注解修饰的类通过无参构造器创建出来,然后存入spring容器当中。
  • @AutoConfigureBefore: 一般都是配合着@Configuration使用,主要用于修饰在类上,然后可以指定该类 在 某类之前进行加载到容器。
  • @AutoConfigureAfter:@AutoConfigureBefore功能一样,他是指定该类 在 某类 之后进行加载到容器当中。

具体的用法请看下面的示例!

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration(
    proxyBeanMethods = false
)
@AutoConfigureBefore
@AutoConfigureAfter
public @interface AutoConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    String value() default "";

    @AliasFor(
        annotation = AutoConfigureBefore.class,
        attribute = "value"
    )
    Class<?>[] before() default {};

    @AliasFor(
        annotation = AutoConfigureBefore.class,
        attribute = "name"
    )
    String[] beforeName() default {};

    @AliasFor(
        annotation = AutoConfigureAfter.class,
        attribute = "value"
    )
    Class<?>[] after() default {};

    @AliasFor(
        annotation = AutoConfigureAfter.class,
        attribute = "name"
    )
    String[] afterName() default {};
}

@AutoConfiguration其实就是一个组合注解。因为一个自动配置类往往需要加很多注解,于是乎springboot就将一些经常用到的注解,给组合到一块,这样就可以做到一个注解拥有三个注解的功能。具体他是如何做到注解聚合到一块的呢,原因是依赖于@AliasFor注解,@AliasFor注解就是起到一个注解传值的作用。想深入了解@AliasFor可以看我的这一篇文章:

https://blog.youkuaiyun.com/weixin_43888891/article/details/126962698?spm=1001.2014.3001.5501

在这里插入图片描述

二、@Configuration

@Configuration注解我们经常用,但是我们很少这样用@Configuration(proxyBeanMethods = false),这里的proxyBeanMethods默认是true,但是这里却设置为了false,那么这个属性到底有什么作用?

@Configuration属于spring当中的注解,感兴趣的可以看一下spring源码当中的解释:https://github.com/spring-projects/spring-framework/blob/main/spring-context/src/main/java/org/springframework/context/annotation/Configuration.java

源码当中解释不是中文,再者一般的也看不懂,我们直接通过代码试验来得出结论:

当他为true的时候,我们在容器中获取到的对象总是同一个,即便是我们调用了创建对象的方法,那获取到的还是同一个。但是当是多例的时候,如果我们调用了创建对象的方法,那就不是同一个了。

(1)自定义一个类,用于测试

public class TestBean1 {
    @Override
    public String toString() {
        return super.toString() + "--我是TestBean1";
    }

    public TestBean1() {
        System.out.println("TestBean1构造器执行了");
    }
}

(2)添加配置类

@Configuration(proxyBeanMethods = true)
public class Myconfig {

    @Bean
    public TestBean1 testBean1() {
        return new TestBean1();
    }
}

(3)添加测试类

@RestController
public class CommonController {

    @Autowired
    private Myconfig myconfig;

    @Autowired
    private TestBean1 testBean1;

    @RequestMapping("/import")
    public void printImportBeanInfo() {
        System.out.println(testBean1);
        System.out.println(myconfig.testBean1());
    }
}

(4)访问接口,得出从容器里面取和直接访问testBean1方法得出来的对象是一个对象,这就是所谓的被代理了

在这里插入图片描述
(5)设置为false@Configuration(proxyBeanMethods = false)

很显然已经不是一个对象了

在这里插入图片描述

三、@AutoConfigureBefore

(1)自定义两个配置类

@Configuration
public class Config1 {

    public Config1() {
        System.out.println("Config1构建了");
    }
}

@Configuration
public class Config2 {

    public Config2() {
        System.out.println("Config2构建了");
    }
}

(2)启动项目测试:默认是先创建的Config1后创建的Config2

在这里插入图片描述

现在是有个需求要求让@Config2先加载,可能这时候有人该说了@Order注解不就可以了吗,其实不是的,@Order值可能会影响注入点的优先级,但请注意,它不会影响单例启动顺序。关于@order我专门整理了一篇文章,供参考学习!
https://blog.youkuaiyun.com/weixin_43888891/article/details/127481825

(3)使用@AutoConfigure相关注解的前提是必须是自动配置类,可能有时候走了狗屎运给你一种错觉还真的配置成功了。

在Config2上添加@AutoConfigureBefore(Config1.class)注解,就是告诉他我要在Config1之前注入容器,只加入注解后再次启动项目会发现没有任何作用!

在这里插入图片描述

在autoconfigure包下就有spring.factories,这个文件配置了自动配置类,springboot会读取这个文件的,我们也可以在自己项目上定义spring.factories,这样我们的配置类对于@AutoConfigureAfter注解就可以生效了。

在这里插入图片描述
(4)自定义spring.factories

在这里插入图片描述

第一行是固定的,后面的就是全类名,虽然只有Config2使用了注解,但是需求是和Config1进行排序,所以这两个都得加。

可能有的人对这里会有疑问,我不使用@AutoConfigureBefore注解,只通过spring.factories下面的配置可以修改这两个配置类的启动顺序吗,答案是不可以的!!! 关于这一点我也通过试验印证过了!

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.gzl.cn.springbootcache.config.Config2,\
com.gzl.cn.springbootcache.config.Config1

(5)测试,成功解决

在这里插入图片描述

四、@AutoConfigureAfter

@AutoConfigureAfter和@AutoConfigureBefore其实是一样的,我这里就不演示了哈,感兴趣的可以自己参照上面进行练习一下。

五、@AutoConfigureOrder

这种也是可以的!当然前提也是需要配置spring.factories

@Configuration
@AutoConfigureOrder(2)
public class Config1 {

    public Config1() {
        System.out.println("Config1构建了");
    }
}

@Configuration
@AutoConfigureOrder(1)
public class Config2 {

    public Config2() {
        System.out.println("Config2构建了");
    }
}

六、源码分析

其实关键的代码还是在AutoConfigurationImportSelector中,将自动配置类从spring.factories加载出来之后会根据条件排序,在selectImports()方法中最后一行代码如下:

在这里插入图片描述

紧接着会走到这个地方,实际上是分了三步排序:

  1. 先按照字母排序
  2. 按照@AutoConfigureOrder进行排序
  3. 按照 @AutoConfigureBefore和@AutoConfigureAfter排序

在这里插入图片描述
从上面配置的顺序可以知道,最终决定权还是在@AutoConfigureAfter、@AutoConfigureBefore这两个注解。

当我们不设置spring.factories的时候,这里面压根都没有这两个类!

在这里插入图片描述

<think>好的,我现在需要帮助用户了解Spring Boot的AutoConfiguration注解,特别是为了面试准备。首先,我得回忆一下自己之前学过的相关知识,并结合用户提供的三个引用内容来整理答案。 用户提到的引用[1]讨论了使用spring.factories配置能否改变配置类的顺序,结论是不可以,必须用@AutoConfigureBefore注解。这说明自动配置的顺序控制是一个需要注意的点,可能在面试中被问到。引用[2]详细解释了@EnableAutoConfiguration的工作机制,包括AutoConfigurationImportSelector的作用,这应该是核心内容。引用[3]提到配置处理器依赖,这可能与如何自定义配置相关,但用户的问题主要集中在AutoConfiguration注解上,所以可能不需要深入这部分,但可以作为扩展点。 接下来,我需要组织信息,确保覆盖以下方面: 1. AutoConfiguration注解的基本作用。 2. 核心机制,如@EnableAutoConfigurationspring.factories文件。 3. 自动配置的加载过程及条件装配。 4. 配置类顺序的控制方法。 5. 常见面试问题,比如原理、如何覆盖自动配置、条件注解等。 需要确保回答结构清晰,分点说明,并引用提供的资料来支持内容。例如,在讲解配置顺序时,必须引用[1]说明仅通过spring.factories无法改变顺序,必须使用特定注解。同时,在解释自动配置流程时,引用[2]中提到的AutoConfigurationImportSelector的作用。 可能还需要注意用户提到的“用于面试”,所以需要整理常见的面试问题,并给出简洁准确的答案,如自动配置原理、条件注解的作用等。此外,要避免技术错误,比如正确区分@EnableAutoConfiguration和@Configuration的区别,以及条件注解如@ConditionalOnClass的使用场景。 最后,检查是否所有引用的内容都正确应用,并确保回答符合用户的要求:结构清晰、真实可靠,符合中文回答要求,数学公式正确(虽然这里可能用不上,但需要注意格式)。同时生成的相关问题需要围绕AutoConfiguration,帮助用户进一步准备面试可能涉及的问题点。</think>### Spring Boot AutoConfiguration 注解详解 #### 1. 核心注解与机制 **@EnableAutoConfiguration** 是 Spring Boot 自动配置的核心入口,通过触发 `AutoConfigurationImportSelector` 类加载并筛选符合条件的配置类[^2]。其关键步骤如下: - **加载候选配置类**:从 `META-INF/spring.factories` 文件中读取 `org.springframework.boot.autoconfigure.EnableAutoConfiguration` 键下的所有配置类。 - **条件筛选**:通过 `@Conditional` 系列注解(如 `@ConditionalOnClass`、`@ConditionalOnMissingBean`)过滤掉不满足当前环境的配置类。 - **注册 Bean**:最终将筛选后的配置类注册到 Spring 容器中。 #### 2. 自动配置类的定义 自动配置类通常标记为 `@Configuration`,并通过 `@Conditional` 注解控制生效条件。例如: ```java @Configuration @ConditionalOnClass(DataSource.class) public class DataSourceAutoConfiguration { // 配置数据源相关 Bean } ``` 此配置仅在类路径中存在 `DataSource` 类时生效。 #### 3. 配置类加载顺序控制 - **默认顺序**:Spring Boot 按 `spring.factories` 中定义的顺序加载配置类。 - **手动调整**:使用 `@AutoConfigureBefore` 或 `@AutoConfigureAfter` 注解显式指定顺序。 **注意**:仅通过 `spring.factories` 调整顺序无效,必须使用注解[^1]。例如: ```java @Configuration @AutoConfigureBefore(OtherConfig.class) public class MyConfig { // 配置内容 } ``` #### 4. 常见面试问题 1. **Spring Boot 自动配置的原理是什么?** 答:基于 `@EnableAutoConfiguration` 触发 `AutoConfigurationImportSelector` 加载 `spring.factories` 中的配置类,通过条件注解筛选后注册 Bean[^2]。 2. **如何覆盖默认的自动配置?** 答:定义自定义 Bean 并标记 `@Primary`,或使用 `@ConditionalOnMissingBean` 让自动配置仅在无用户自定义 Bean 时生效。 3. **@ConditionalOnClass 的作用是什么?** 答:当类路径中存在指定类时,才启用当前配置类。 4. **自动配置类之间如何控制加载顺序?** 答:通过 `@AutoConfigureBefore` 或 `@AutoConfigureAfter` 注解显式指定顺序。 5. **spring.factories 文件的作用?** 答:定义所有候选的自动配置类列表,供 `AutoConfigurationImportSelector` 读取和筛选。 #### 5. 实践建议 - **调试自动配置**:启动时添加 `--debug` 参数,日志会输出生效的自动配置类及原因。 - **自定义 Starter**:遵循 Spring Boot 规范,将自动配置类定义在 `spring.factories` 中,并合理使用条件注解
评论 23
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

怪 咖@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值