springboot(二)自动化配置源码解析

   日期:2020-10-13     浏览:106    评论:0    
核心提示:@EnableAutoConfiguration 是开启自动配置的注解,在创建的 SpringBoot 项目中并不能直接看到此注解,它是由组合注解@SpringBootApplication 引入的。 让我们先从程序的启动类开始分析. 启动类和@SpringBootApplication 注解@SpringBootApplicationpublic class SpringLearnApplication { public static void main(...

     @EnableAutoConfiguration 是开启自动配置的注解,在创建的 SpringBoot 项目中并不能直接看到此注解,它是由组合注解@SpringBootApplication 引入的。

    让我们先从程序的启动类开始分析. 

     启动类和@SpringBootApplication 注解

@SpringBootApplication
public class SpringLearnApplication {
    public static void main(String[] args) {
        SpringApplication. run(DemoApplication. class, args);
    }
}

      Spring Boot 项目创建完成会默认生成-个*Application 的入口类。 在默认情况下,无论是通过 IDEA 还是通过官方创建基于 Maven 的 Spring Boo 项目,入口类的命名规则都是artifactld+Application。
     这个启动类中最重要的就是@SpringBootApplication注解. 它是 Spring Boot 项目的核心注解,用于开启自动配置,准确说是通过该注解内组合的@EnableAutoConfiguration 开启了自动配置。

     @SpringBootApplication 部分源代码如下: 

   

@Target(ElementType . TYPE)
@Retent ion(Retent ionPolicy . RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan( excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM,classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
    //排除指定自动配置类
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};
    //排除指定自动配置类名
    @AliasFor( annotation = EnableAutoConfiguration. class)
    String[] excludeName() default {}
    //指定扫描的基础包,激活炷解组件的初始化
    @AliasFor( annotation = ComponentScan. class, attribute = "basePackages")
    String[] scanBasePackages() default {};
    //指定扫描的类,用于初始化
    @AliasFor( annotation = ComponentScan. class, attribute = "basePackageClass")
    Class<?>[] scanBasePackageClasses() default {};
    //指定是否代理@Bean 方法以强制执行 bean 的生命周期行为
    @AliasFor( annotation = Configuration.class)
    boolean proxyBeanMethods() default true ; 
}

通过源代码可以看出,该注解提供了以下成员属性(注解中的成员变量以方法的形式体现)。

  1. exclude:根据类(Class) 排除指定的自动配置,该成员属性覆盖了@SpringBoot-Application中组合的@ EnableAutoConfiguration 中定义的 exclude 成员属性。
  2. excludeName :根据类名排除指定的自动配置,覆盖了@ EnableAutoConfiguration 中的excludeName 的成员属性。
  3. scanBasePackages:指定扫描的基础 package,用于激活@Component 等注解类的初始化。
  4. scanBasePackageClasses:扫描指定的类,用于组件的初始化。
  5. proxyBeanMethods:指定是否代理@ Bean 方法以强制执行 bean 的生命周期行为。此功能需要通过运行时生成 CGLIB 子类来实现方法拦截。该子类有一定的限制,比如配置类及其方法不允许声明为 final 等。
    proxyBeanMethods 的默认值为 true,允许配置类中进行 inter-beanreferences (bean 之 间的引用)以及对该配置的@Bean 方法的外部调用。如果@Bean 方法都是自包含的,并且仅提供了容器使用的普通工程方法的功能,则可设置为 false,避免处理 CGLIB 子类。SpringBoot 2.2 版本上市后新增该成员属性,后面章节涉及的自动配置类中基本都会用到proxyBeanMethods,一 般情况下都配置为 false。

   通过以上源代码我们会发现,Spring Boot 中大量使用了@AliasFor 注解,该注解用于桥接到其他注解,该注解的属性中指定了所桥接的注解类。如果点进去查看,会发现@SpringBootApplication 定 义的属性在其他注解中已经定义过了。之所以使用@AliasFor注解并重新在@SpringBootApplication 中定义,更多是为了减少用户使用多注解带来的麻烦。
@SpringBootApplication注解的组合结构如下图: 

    @SpringBootApplication除 了组合元注解之外,其核心作用还包括:激活SpringBoot 自 动 配 置 的 @EnableAutoConfiguration 、 激 活 @Component 扫 描 的@ComponentScan、激活配置类的@Configuration。其中@ComponentScan,@Configuration在Spring中常用到, 这里分析一下@EnableAutoConfiguration的功能.


注解@EnableAutoConfiguration功能解析

       在未使用 Spring Boot 的情况下,Bean 的生命周期由 Spring 来管理,然而 Spring 无法自动配置@Configuration 注解的类。而 Spring Boot 的核心功能之- 就是根据约定自动管理该注解标注的类。用来实现该功能的组件是@EnableAutoConfiguration 注解。

        @EnableAutoConfiguration 的主要功能是启动 Spring 应用程序上下文时进行自动配置,它会尝试猜测并配置项目可能需要的 Bean。自动配置通常是基于项目 classpath 中引入的类和已定义的 Bean 来实现的。在此过程中,被自动配置的组件来自项目自身和项目依赖的 jar包中。

     例如: 如 果 将 tomcat-embedded.jar 添 加 到 classpath 下 , 那 么@EnableAutoConfiguration 会认为你准备用 TomcatServletWebServerFactory 类,并帮你初始化相关配置。与此同时,如果自定义了基于 ServletWebServerFactory 的 Bean ,那么@EnableAutoConfiguration 将不会进行 TomcatServletWebServerFactory 类的初始化。这一系列的操作判断都由 Spring Boot 来完成。

    @EnableAutoConfiguration 注解的源码

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
    //根据类(Class) 排除指定的自动配置
    Class<?>[] exclude() default {};
    //根据类名排除指定的自动配置
    String[] excludeName() default {};
}

    @EnableAutoConfiguration 会猜 测你需要使用的 Bean,但如果在实战中你并不需要它预置初始化的 Bean,可通过该注解的 exclude 或 excludeName 参数进行有针对性的排除。比如,当不需要数据库的自动配置时,可通过以下两种方式让其自动配置失效。

//通过@SpringBootApplication 排除 DataSourceAutoConfiguration
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class SpringLearnApplication {

}
或:
//通过@EnableAutoConfiguration 排除 DataSourceAutoConfiguration
@Configuration
@EnableAutoConfiguration( exclude = DataSourceAutoConfiguration.class)
public class DemoConfiguration {

}

    被@EnableAutoConfiguration 注 解的类所在 package 还具有特定的意义,通常会被作为扫描注解@Entity 的根路径。这也是在使用@SpringBootApplication 注解时需要将被注解的类放在顶级 package 下的原因,如果放在较低层级,它所在 package 的同级或上级中的类就无法被扫描到。

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服