SpringBoot学习笔记16 - 类的自动装配

1、剖析@SpringBootApplication注解


创建一个SpringBoot工程后,SpringBoot会为用户提供一个Application类,该类负责项目的启动:

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

这是一个被@SpringBootApplication注解的类,该注解完成了SpringBoot中类的自动装配任务:

@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 {
   
	...
}

抛却元注解不谈,@SpringBootApplication继承了三个注解:

  • @SpringBootConfiguration
    /**
     * Indicates that a class provides Spring Boot application
     * {@link Configuration @Configuration}. Can be used as an
     * alternative to the Spring's standard @Configuration 
     * annotation so that configuration can be found
     * automatically (for example in tests).
     *
     * Application should only ever include one 
     * @SpringBootConfiguration and most idiomatic Spring Boot 
     * applications will inherit it from @SpringBootApplication.
     */
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration
    public @interface SpringBootConfiguration {
         
    	...
    }
    
    在说明中提到,@SpringBootConfiguration注解是用来替代Spring的@Configuration,方便SpringBoot自动找到配置。
  • @ComponentScan
    /**
     * Configures component scanning directives
     * for use with Configuration classes.
     * Provides support parallel with Spring XML's
     * <context:component-scan> element.
     *
     * Either #basePackageClasses or #basePackages
     * (or its alias #value} may be specified to
     * define specific packages to scan. If specific
     * packages are not defined, scanning will occur
     * from the package of the class that declares
     * this annotation.
     *
     * Note that the <context:component-scan> element
     * has an annotation-config attribute; however,
     * this annotation does not. This is because
     * in almost all cases when using @ComponentScan,
     * default annotation config processing
     * (e.g. processing @Autowired and friends)
     * is assumed. Furthermore, when using 
     * AnnotationConfigApplicationContext,
     * annotation config processors are always
     * registered, meaning that any attempt to disable
     * them at the @ComponentScan level would be ignored.
     */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Repeatable(ComponentScans.class)
    public @interface ComponentScan {
         
    	...
    }
    
    在说明中我们可以得知:@ComponentScan只负责指定要扫描的包,并没有装配其中的类,这个真正装配这些类是@EnableAutoConfiguration
  • @EnableAutoConfiguration
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import(AutoConfigurationImportSelector.class)
    public @interface EnableAutoConfiguration {
         
    	...
    }
    
    该类真正完成了SpringBoot对于类的装配工作,具体内容在后续会作出解释。

2、以@Enable开头的注解


以@Enable开头的注解(@EnableXxx)一般用于开启某一项功能,是为了简化代码的导入。它是一个组合注解,一般情况下@EnableXxx注解中都会组合一个@Import注解,而该@Import注解用于导入指定的类,而被导入的类一般有三种:

2.1、配置类

  • 类的特征:@Import中指定的类一般以Configuration结尾
  • 类的配置:该类上会注解@Configuration
  • 类的案例:定时任务启动注解:SchedulingConfiguration
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Import(SchedulingConfiguration.class)
    @Documented
    public @interface EnableScheduling {
         
    }
    

2.2、选择器

  • 类的特征:@Import中指定的类一般以 Selector 结尾
  • 类的配置:该类直接或间接实现了ImportSelector接口,表示当前类会根据条件选择导入不同的类。
  • 类的案例:Redis配置类:CachingConfigurationSelector
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(CachingConfigurationSelector.class)
    public @interface EnableCaching {
         
    	...
    }
    
    public class CachingConfigurationSelector extends AdviceModeImportSelector<EnableCaching> {
         
    	...
    	@Override
    	public String[] selectImports(AdviceMode adviceMode) {
         
    		switch (adviceMode) {
         
    			case PROXY:
    				return getProxyImports();
    			case ASPECTJ:
    				return getAspectJImports();
    			default:
    				return null;
    		}
    	}
    	...
    }
    

2.3、注册器

  • 类的特征:@Import 中指定的类一般以 Registrar 结尾。
  • 类的配置:该类直接或间接实现了ImportBeanDefinitionRegistrar接口,用于导入注册器,该类可以在代码运行时动态注册指定类的实例。
  • 类的案例:AspectJ:AspectJAutoProxyRegistrar
    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(AspectJAutoProxyRegistrar.class)
    public @interface EnableAspectJAutoProxy 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值