金晶科技完成新一轮融资扩大新生产场地
06-17
简介在花子之前的博文《Spring Boot 核心运行原理介绍》中,我们初步了解了Spring Boot的核心运行原理,并知道@EnableAutoConfiguration是一个用于启用自动配置的注解。但是创建过Spring Boot项目的读者肯定会说我们没有直接看到这个注解。
其实之前我也提到过,是通过组合注解@SpringBootApplication引入的。至于@EnableAutoConfiguration的解释,我稍后再深入源码中。
本文首先介绍组合注解@SpringBootApplication。好了,废话不多说,我们看下面的介绍: 主要内容 1. 创建 Spring Boot 项目。
首先我们打开Intellij IDEA开发工具,选择File -> New -> Project然后打开New Project,选择Spring Initializr【这个是用来创建Spring Boot项目的】:选择Next,打开Project Metadata【这里可以配置一些项目的基本信息]:继续下一步并打开依赖项[如有必要,添加其他依赖项]:继续下一步并选择您的 Spring Boot 项目位置:最后单击完成。注意:在新创建的项目中,如果由于Spring Boot版本问题导致项目报错,则尝试其他版本。
2、Spring Boot入口类上述新建的项目创建完成后,会默认生成一个XXXApplication入口类。默认情况下,该类的命名规则为artifactId + Application【artifactId首字母大写】:如上图所示,DemoApplication是我们Spring Boot项目的入口类。
代码如下: 代码语言:java copy package com.example .demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DemoApplication { public static void main(String[ ] args) { SpringApplication.run(DemoApplication.class, args); }}在上述Spring Boot入口类DemoApplication中,唯一的注解是@SpringBootApplication。前面我们提到,它通过其内部组合@EnableAutoConfiguration来开启自动配置功能。
我们来详细介绍一下@SpringBootApplication注解: 3.@SpringBootApplication介绍 首先看@SpringBootApplication的源码【版本:2.7.9】: 代码语言:java copy @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 {/** * 排除特定的自动配置类,使其永远不会被应用 * @return 要排除(禁用)的类 */@AliasFor(annotation = EnableAutoConfiguration.class)Class>[] except() default {};/** * 排除特定的自动配置类名称以确保它们永远不会被应用 * @return 要排除的自动配置类名称 * @since 1.3.0 */@AliasFor(annotation = EnableAutoConfiguration.class) String[ ] exceptName() default {};/** * 用于扫描带注释组件的基础包。使用 {@link #scanBasePackageClasses} 为基于字符串的包名称提供类型安全的替代方案。
*
* 注意:该设置仅对{@code @ComponentScan}注解有效,不影响{@code @Entity}扫描或Spring Data的{@link Repository}扫描。 * 对于这些情况,您应该添加 {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} 和 * {@code @Enable...Repositories} 注释。
* @return 需要扫描的基础包 * @since 1.3.0 */@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")String[] scanBasePackages() default {};/** * 用于指定需求 一种扫描包中带注释组件的类型安全方法。将扫描包含指定类的包。
*
* 考虑在每个包中创建一个特殊的空类或接口,仅用于此属性引用的标记类。 *
* 注意:该设置仅对{@code @ComponentScan}注解有效,不影响{@code @Entity}扫描或Spring Data的{@link Repository}扫描。
* 对于这些情况,您应该添加 {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} 和 * {@code @Enable...Repositories} 注释。* @return 待扫描的基础包 * @since 1.3.0 */@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")Class>[] scanBasePackageClasses() default {};/** * 使用对于为 Spring 容器中检测到的组件命名的 {@link BeanNameGenerator} 类。
*
* {@link BeanNameGenerator}接口本身的默认值表明应该使用处理此{@code @SpringBootApplication}注解的扫描器继承的bean名称生成器, * 例如默认的{@link AnnotationBeanNameGenerator}或在引导中提供给应用程序上下文的任何自定义实例。 * @return {@link BeanNameGenerator} 要使用 * @see SpringApplication#setBeanNameGenerator(BeanNameGenerator) * @since 2.3.0 */@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")Class extends BeanNameGenerator> nameGenerator () default BeanNameGenerator.class;/** * 指定是否应代理 {@link Bean @Bean} 方法以强制执行 Bean 的生命周期行为,例如,即使直接调用 {@code @Bean} 方法在用户代码中, * 也可以返回共享的单例 bean 实例。
此功能需要方法拦截,通过运行时生成的 CGLIB 子类实现,其中包括一些限制,例如不允许将配置类及其方法声明为 {@code Final}。*
* 默认值为 {@code true},它允许配置类中的“bean 间引用”,同时允许从另一个配置类中调用此配置的 {@code @Bean} 方法。
* 如果每个特定于配置的 {@code @Bean} 方法是自包含的,并且设计为供容器使用的普通工厂方法,则可以将此标志切换为 {@code false}, * 以避免 CGLIB 子类处理。 *
* 关闭 Bean 方法拦截实际上会单独对待 {@code @Bean} 方法,就好像它们是在非 {@code @Configuration} 类上声明的,即“@Bean Lite 模式” * (参见{@link Bean @Bean 文档})。
因此,该行为相当于删除 {@code @Configuration} 注解。 * @since 2.2 * @return 是否代理{@code @Bean}方法 */@AliasFor(annotation = Configuration.class)boolean proxyBeanMethods() default true;} 通过查看上面的源码,我们可以看到@SpringBootApplication注解提供了以下成员属性【这里大家默认都知道注解中的成员变量是以方法的形式存在的】:exclusion:排除指定的基于类(Class)的自动配置。
该成员属性覆盖了 @EnableAutoConfiguration 中定义并结合在 @SpringBootApplication 中的排除成员属性。 exceptName:根据类名排除指定的自动配置,覆盖@EnableAutoConfiguration中定义的excludeName成员属性。
scanBasePackages:指定扫描的基础包,用于扫描带有注解组件的基础包,例如包含@Component等注解的组件。 scanBasePackageClasses:指定扫描的类,用于相关组件的初始化。
nameGenerator:BeanNameGenerator 类,用于命名 Spring 容器中检测到的组件。 proxyBeanMethods:指定是否对 @Bean 方法进行编码以强制执行 bean 的生命周期行为。
该功能需要通过在运行时生成CGLIB子类来实现方法拦截。但是,它包含某些限制。
例如,配置类及其方法不允许被声明为final。 proxyBeanMethods 的默认值为 true,允许配置类中的 bean 间引用以及对配置的 @Bean 方法的外部调用。
如果@Bean方法都是自包含的并且仅提供容器使用的正常工程方法的功能,则可以将它们设置为false以避免处理CGLIB子类。另外,从源码中的@since 2.2中我们还可以看到,这个属性是在Spring Boot 2.2版本中添加的。
细心的读者可能看过上面的源码,发现@AliasFor注解大量使用在@SpringBootApplication注解的成员属性上。这个注解的作用是什么? @AliasFor注解用于桥接其他注解,其注解属性指定桥接的注解类。
如果我们点击注解属性配置的注解,可以看到@SpringBootApplication注解的成员属性实际上已经在其他注解中定义了。之所以在@SpringBootApplication中使用并重新定义@AliasFor注解,主要是为了减少用户使用多个注解的麻烦。
知识扩展: 简单总结一下@AliasFor的作用: 定义别名关系:通过在注解属性上使用@AliasFor注解,可以在一个属性和另一个属性之间建立别名关系。这意味着在使用注解时,可以使用alias属性来设置目标属性的值。
属性互操作性:通过在两个属性上使用@AliasFor注解并将它们的属性属性设置为彼此,可以实现属性之间的双向关联。这意味着当设置其中一个属性的值时,另一个属性会自动分配相同的值。
注解继承:当一个注解A使用@AliasFor注解指定另一个注解B的属性作为自己的别名属性时,如果该类使用了注解A,则注解B的相关属性也会被相应设置。 Spring Boot早期版本中没有@SpringBootConfiguration注解。
它是后来版本中新添加的,它结合了@Configuration注解,如下图: @EnableAutoConfiguration注解结合了@AutoConfigurationPackage注解,如下图: 除了一些元注解和基本注解之外,我们用一个类图来描述@SpringBootApplication注解的组合结构: 从上图我们可以总结出@SpringBootApplication注解的核心作用,如下: 结合@EnableAutoConfiguration用于启用Spring Boot的自动配置功能;与@ComponentScan结合,用于激活@Component及其他注解类的初始化;与@SpringBootConfiguration结合,用于标识一个类作为配置类,用于Spring应用上下文中的配置。综上所述,本文回顾了@SpringBootApplication注解的源码,并介绍了它的成员属性和组合注解。
这些内容将为我们后续的源码学习打下基础。
版权声明:本文内容由互联网用户自发贡献,本站不拥有所有权,不承担相关法律责任。如果发现本站有涉嫌抄袭的内容,欢迎发送邮件 举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。
标签:
相关文章
06-17
06-18
06-18
06-18
06-18
最新文章
【玩转GPU】ControlNet初学者生存指南
【实战】获取小程序中用户的城市信息(附源码)
包雪雪简单介绍Vue.js:开学
Go进阶:使用Gin框架简单实现服务端渲染
线程池介绍及实际案例分享
JMeter 注释 18 - JMeter 常用配置组件介绍
基于Sentry的大数据权限解决方案
【云+社区年度征文集】GPE监控介绍及使用