一文详解Spring Boot自动配置原理和自定义封装实现starter

1.概述

我们今天可以来分析一下Spring Boot自动配置的实现原理和自己手动封装一个starter了。

我们一直在强调Spring Boot能成为当下主流首选开发框架的主要原因在于其核心思想:约定大于配置,自动配置,条件装配。基于这些特性使得Spring Boot集成其他框架非常简单快捷。

使用Spring Boot创建的项目启动、执行也非常简单,只需要执行启动类的main()方法即可,不需要做其他操作,Spring Boot会自动装配相关所需依赖和配置。

@SpringBootApplication
public class CommonDemoApplication {
​
    public static void main(String[] args) {
      SpringApplication.run(CommonDemoApplication.class, args);
    }
​
}
复制代码

2.Spring Boot自动配置原理

从上面项目启动类可以看出,没有什么复杂的启动逻辑,就只使用一个注解@SpringBootApplication,这就是Spring Boot自动配置的核心入口所在,其定义如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
​
  // 排除掉自动配置的class
  @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 = "basePackageClasses")
  Class[] scanBasePackageClasses() default {};
​
  // beanName生成器
  @AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
  Class nameGenerator() default BeanNameGenerator.class;
​
  // 配置类代理模式:proxyBeanMethods:代理bean的方法
  //     Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
  //     Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
  @AliasFor(annotation = Configuration.class)
  boolean proxyBeanMethods() default true;
​
}
​
复制代码

从定义可知@SpringBootApplication是一个复合注解,所以接下来我们逐一看看其关联使用的注解。

2.1 @SpringBootConfiguration

@SpringBootConfiguration的定义如下:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
​
  @AliasFor(annotation = Configuration.class)
  boolean proxyBeanMethods() default true;
​
}
​
复制代码

从定义可知,该注解就是一个配置类注解,其作用和属性和@Configuration注解一样,只是这里语义化罢了,就像@Controller@Component一个道理。

2.2 @EnableAutoConfiguration

从名字上看,@EnableAutoConfiguration是自动配置核心所在,先看看其定义:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
​
  String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
​
  Class[] exclude() default {};
​
  String[] excludeName() default {};
​
}
复制代码

可以看出@EnableAutoConfiguration也是一个复合注解,所以我们接下来对其关联的注解进行解析:

2.2.1 @AutoConfigurationPackage

该注解的作用是将添加该注解的类所在的package作为自动配置package 进行管理,也就是说当Spring Boot应用启动时默认会将启动类所在的package作为自动配置的package。老规矩,先看看其定义:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Regist

你可能感兴趣的:(spring,boot,spring,java)