springboot 初始化加载过程 条件注解

在路上 / 2023-08-03 / 原文

官网解释:https://docs.spring.io/spring-boot/docs/3.0.9/reference/html/features.html#features.developing-auto-configuration.condition-annotations

从其他博客粘过来的表格:

条件注解Condition处理类实例解释
@ConditionalOnBean OnBeanCondition @ConditionalOnBean(DataSource.class) Spring容器中不存在对应的实例生效
@ConditionalOnMissingBean OnBeanCondition @ConditionalOnMissingBean(name = "redisTemplate") Spring容器中不存在对应的实例生效
@ConditionalOnSingleCandidate OnBeanCondition @ConditionalOnSingleCandidate(FilteringNotifier.class)

Spring容器中是否存在且只存在一个对应的实例,

  或者虽然有多个但 是指定首选的Bean生效

@ConditionalOnClass OnClassCondition @ConditionalOnClass(RedisOperations.class) 类加载器中存在对应的类生效
@ConditionalOnMissingClass OnClassCondition @ConditionalOnMissingClass(RedisOperations.class) 类加载器中不存在对应的类生效
@ConditionalOnExpression OnExpressionCondition @ConditionalOnExpression(“’${server.host}’==’localhost’”) 判断SpEL 表达式成立生效
@ConditionalOnJava OnJavaCondition @ConditionalOnJava(JavaVersion.EIGHT) 指定Java版本符合要求生效
@ConditionalOnProperty OnPropertyCondition

@ConditionalOnProperty(prefix = “spring.aop”, name = “auto”,

        havingValue = “true”, matchIfMissing = true)

应用环境中的属性满足条件生效
@ConditionalOnResource OnResourceCondition @ConditionalOnResource(resources=”mybatis.xml”) 存在指定的资源文件生效
@ConditionalOnWebApplication OnWebApplicationCondition   当前应用是Web应用生效
@ConditionalOnNotWebApplication OnWebApplicationCondition   当前应用不是Web应用生效

       上面的扩展注解我们可以简单的分为以下几类:

  • Bean作为条件:@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnSingleCandidate。
  • 类作为条件:@ConditionalOnClass、@ConditionalOnMissingClass。
  • SpEL表达式作为条件:@ConditionalOnExpression。
  • JAVA版本作为条件: @ConditionalOnJava
  • 配置属性作为条件:@ConditionalOnProperty。
  • 资源文件作为条件:@ConditionalOnResource。
  • 是否Web应用作为判断条件:@ConditionalOnWebApplication、@ConditionalOnNotWebApplication。

以上是理解springboot默认加载的基础。

1.

 2.

 3.

 4.

 5.

 6.

 7.截图放不下了,最终会指向 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

 8. imports 局部截图。这里包含了springboot想为你加载的所有模块的 *AutoConfiguration

 9.当然,这些自动配置类并不是全部都会用到,会经过筛选处理

 10.现在我们看一下 WebMvcAutoConfiguration.. 如果满足这三个条件。就不会过滤掉,看看上面的筛选条件。

 11.看看WebMvcAutoConfiguration 做了什么。 根据条件注解,看看加载 Bean的条件,。思考如何定义自己的 bean并替换它们吧!

 


 

 12.自定义 WebMvcConfigurer 进行 默认配置类的扩展。这里代码仅供参考,主要讨论扩展原理

//@EnableWebMvc    加了这个会使Springmvc自动配置失效
@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    /**
     * 添加视图控制器
     * 立即访问
     * <mvc:view-controller path="/" view-name="index" />
     *
     * @param registry
     */
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/tuling").setViewName("hello");
    }

    /**
     * 添加拦截器
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TimeInterceptor())     //添加拦截器
                .addPathPatterns("/**")    // 拦截映射规则
                .excludePathPatterns("/pages/**");  // 设置排除的映射规则

        // 添加国际化拦截器
        registry.addInterceptor(new LocaleChangeInterceptor())
                .addPathPatterns("/**");    // 拦截映射规则
    }

    /**
     * 全局CORS配置
     *
     * @param
     * @Override public void addCorsMappings(CorsRegistry registry) {
     * registry.addMapping("/user/*")   // 映射服务器中那些http接口运行跨域访问
     * .allowedOrigins("http://localhost:8081")     // 配置哪些来源有权限跨域
     * .allowedMethods("GET","POST","DELETE","PUT");   // 配置运行跨域访问的请求方法
     * }
     */


    @Bean
    public LocaleResolver localeResolver() {
        CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
        // 可以设置过期时间
        cookieLocaleResolver.setCookieMaxAge(60 * 60 * 24 * 30);
        cookieLocaleResolver.setCookieName("locale");
        return cookieLocaleResolver;
    }
}
代码仅供参考

13.书接前文,还是在 WebMvcAutoConfiguration 里 

WebMvcAutoConfigurationAdapter 通过
@Import(EnableWebMvcConfiguration.class) 导入 EnableWebMvcConfiguration 
EnableWebMvcConfiguration 继承了 DelegatingWebMvcConfiguration

 14。

DelegatingWebMvcConfiguration作为一个配置类,将容器里所有的 webMvcConfigurer 全部注入进了 configurers.
注意:重写的 WebMvcConfigurationSupport 方法,都是在处理 configurers

 15. @EnableWebMvc. 是自动配置失效的原理

注意:13步里的 Configuration equivalent to @EnableWebMvc.

 如下图:没有 WebMvcConfigurationSupport 类 WebMvcAutoConfiguration 才会生效 

而 @EnableWebMvc注解导入的 DelegatingWebMvcConfiguration 继承自 WebMvcConfigurationSupport 
所以 添加 @EnableWebMvc 后 WebMvcAutoConfiguration 自动配置就会失效